JDBC之事务隔离级别以及ACID特性
JDBC之事务隔离级别以及ACID特性
事务隔离级别:
1.更新遗失(Lost update)
两个事务都同时更新一行数据,但是第二个事务却中途失败退出,导致对数据的两个修改都失效了。这是因为系统没有执行任何的锁操作,因此并发事务并没有被隔离开来。
基本上就是指某个事务对字段进行更新的信息,因另一个事务的介入而遗失更新效力。举例来说,若某个字段数据原为ZZZ,用户A、B 分别在不同的时间点对同一字段进行更新事务,如下图:

单就用户A 的事务而言,最后字段应该是OOO,单就用户B 的事务而言,最后字段应该是ZZZ。在完全没有隔离两者事务的情况下,由于用户B 撤销操作时间在用户A 确认之后,因此最后字段结果会是ZZZ,用户A看不到他新确认的OOO 结果,用户A 发生更新遗失问题。
如果要避免更新遗失问题,需要设置隔离级别为“可读取未确认”(Read Uncommitted),如果一个事务已经开始写数据,则另外一个数据则不允许同时进行写操作,但允许其他事务读此行数据。
该隔离级别可通过“排他写锁”实现。JDBC 可通过Connection 的setTransactionIsolation()设置为TRANSACTION_UNCOMMITTED 来提示数据库指定此隔离行为。
实现后如下图:

提示数据库“可读取未确认”的隔离层次之后,数据库至少得保证事务能避免更新遗失问题,通常这也是具备事务功能的数据库引擎会采取的最低隔离层级。不过这个隔离层级读取错误数据的机率太高,一般默认不会采用这种隔离级别。
2.脏读(Dirty read)
两个事务同时进行,其中一个事务更新数据但未确认,另一个事务就读取数据,就有可能发生脏读问题,也就是读到所谓脏数据、不干净、不正确的数据。如下图:

如果要避免脏读问题,可以设置隔离层级为“可读取确认”(Read committed)。这可以通过“瞬间共享读锁”和“排他写锁”实现。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。也就是事务读取的数据必须是其他事务已确认的数据。JDBC 可通过Connection 的setTransactionIsolation()设置为TRANSACTION_COMMITTED 来提示数据库指定此隔离行为。
实现后如下图所示:

提示数据库“可读取确认”的隔离层次之后,数据库至少得保证事务能避免脏读与更新遗失问题。
3.无法重复的读取(Unrepeatable read)
某个事务两次读取同一字段的数据并不一致。如下图:

如果要避免无法重复的读取问题, 可以设置隔离层级为“可重复读取”(Repeatable read),这可以通过“共享读锁”和“排他写锁”实现。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。也就是同一事务内两次读取的数据必须相同。JDBC 可通过Connection 的setTransactionIsolation()设置为TRANSACTION_REPEATABLE_READ 来提示数据库指定此隔离行为。
实现后如下图所示:

在数据库上这个做法影响性能较大,另一个基本做法是事务正在读取但尚未确认前,另一事务会在暂存表格上更新。提示数据库“可重复读取”的隔离层次之后,数据库至少得保证事务能避免无法重复读取、脏读与更新遗失问题。
4.幻读(Phantom read)
同一事务期间,读取到的数据笔数不一致。例如,事务A 第一次读取得到五笔数据,此时事务B 新增了一笔数据,导致事务B 再次读取得到六笔数据。
如果隔离行为设置为可重复读取,但发生幻读现象,可以设置隔离层级为“可循序”(Serializable),它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。也就是在有事务时若有数据不一致的疑虑,事务必须可以按照顺序逐一进行。JDBC 可通过Connection 的setTransactionIsolation()设置为TRANSACTION_SERIALIZABLE 来提示数据库指定此隔离行为。
隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed。它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、虚读和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。
下面是隔离行为与可预防的问题
|
隔离行为 |
更新遗失 |
脏读 |
无法重复读取 |
幻读 |
|
可读取未确认Read Uncommitted |
预防 |
|
|
|
|
可读取确认 Read Uncommitted |
预防 |
预防 |
|
|
|
可重复读取 Repeatable read |
预防 |
预防 |
预防 |
|
|
可循序 Serializable |
预防 |
预防 |
预防 |
预防 |
数据库事务的ACID特性:
1. 原子性(Atomicity)
整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
例如:银行刷卡业务,当消费的时候A顾客的卡钱减少,然后B商城的账户加钱,只有当这2个操作都成功的时候才可以进行提交,否则都必须回滚。这就是事务的原子性,因为这2个操作不可以分开。
2. 一致性(Consistency)
在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。
例如:有表A和表B,表A中的一个字段aa是表B中bb字段的外键,并且bb字段是必填的,当在B表中插入数据的时候如果bb字段的值在A表中没有,则事务必须回滚否则会破坏数据库的完整性约束。
3. 隔离性(Isolation)
两个事务的执行是互不干扰的,一个事务不可能看到其他事务运行时,中间某一时刻的数据。
例如:A顾客银行卡刷的钱与B顾客互相不影响。
4. 持久性(Durability)
在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
例如:在A顾客消费成功后,银行卡的钱不可以被回滚。
JDBC之事务隔离级别以及ACID特性的更多相关文章
- Spring事务隔离级别和传播特性
相信每个人都被问过无数次Spring声明式事务的隔离级别和传播机制吧!今天我也来说说这两个东西. 加入一个小插曲, 一天电话里有人问我声明式事务隔离级别有哪几种, 我就回答了7种, 他问我Spring ...
- Spring事务隔离级别和传播特性(转)
相信每个人都被问过无数次Spring声明式事务的隔离级别和传播机制吧!今天我也来说说这两个东西. 加入一个小插曲,一天电话里有人问我声明式事务隔离级别有哪几种,我就回答了7种,他问我Spring的版本 ...
- 【MySQL】事务隔离级别及ACID
注:begin或start transaction并不是一个事务的起点,而是在执行它们之后的第一个操作InnoDB表的语句,事务才真正开始.start transaction with consist ...
- 数据库事务的四大特性以及4种事务的隔离级别-以及对应的5种JDBC事务隔离级别
本篇讲诉数据库中事务的四大特性(ACID),并且将会详细地说明事务的隔离级别. 如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性: ⑴ 原子性(Atomicity) 原子性是指事务 ...
- 【概念原理】四种SQL事务隔离级别和事务ACID特性
摘要: SQL事务隔离级别和事务的ACID特性 事务是一组读写操作,并且具有只有所有操作都成功才算成功的特性. 事务隔离级别 SQL事务隔离级别由弱到强分别是:READ_UNCOMMITTED.R ...
- 什么是事务?事务的四个特性(ACID)?并发事务带来哪些问题?事务隔离级别都有哪些?事务的传播特性
什么是事务? 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消.也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做. 事物的四个 ...
- 事务和JDBC事务隔离级别
与事务相关的理论 mysql事物隔离级别:http://mj4d.iteye.com/blog/1744276 事务(Transaction): 是并发控制的单元,是用户定义的一个操作序列.这些操作要 ...
- 事务、事务特性、事务隔离级别、spring事务传播特性
事务.事务特性.事务隔离级别.spring事务传播特性 1.什么是事务: 事务是程序中一系列严密的操作,所有操作执行必须成功完成,否则在每个操作所做的更改将会被撤销,这也是事务的原子性(要么成功, ...
- 什么是事务、事务特性、事务隔离级别、spring事务传播特性
1.什么是事务: 事务是程序中一系列严密的操作,所有操作执行必须成功完成,否则在每个操作所做的更改将会被撤销,这也是事务的原子性(要么成功,要么失败). 2.事务特性: 事务特性分为四个:原子性(At ...
随机推荐
- string.format大全
字符串的数字格式 stringstr1 =string.Format("{0:N1}",56789); //result: 56,789.0 strin ...
- Jquery zTree实例
zTree[简单介绍] zTree 是利用 JQuery 的核心代码,实现一套能完毕大部分经常使用功能的 Tree 插件 兼容 IE.FireFox.Chrome 等浏览器 在一个页面内可同一时候生成 ...
- 8.无法訪问developer.android.com的解决方式。
问题:无法訪问developer.android.com,就无法知道Android的最新信息. 解决的方法:寻找国外的代理ip,比方http://www.xici.net.co/上面的国外代理ip. ...
- 如何将经纬度利用Google Map API显示C# VS2005 Sample Code
原文 如何将经纬度利用Google Map API显示C# VS2005 Sample Code 日前写了一篇如何用GPS抓取目前所在,并回传至资料库储存,这篇将会利用这些回报的资料,将它显示在地图上 ...
- C语言库函数大全及应用实例九
原文:C语言库函数大全及应用实例九 [编程资料]C语言库函数大全及应用实例九 函数名: mktemp 功 ...
- Android DES AES MD5加密
AES加密: <span style="font-size:18px;">package com.example.encrypdate.util; import jav ...
- Sample Page
This is an example page. It's different from a blog post because it will stay in one place and will ...
- Scala很难!
Scala很难! 本文是从 Yes, Virginia, Scala is hard 这篇文章翻译而来. 首先要说的是,我是一个Scala粉丝,我作为一个Scala语言的倡导者差不多有5年历史了.我写 ...
- proxool的配置
//依赖的包:commons-logging-api-1.1.jar,commons-logging-1.0.4.jar,proxool-0.9.1.jar,proxool-cglib.jar,cgl ...
- SpringMVCURL请求到Action的映射规则
SpringMVC学习系列(3) 之 URL请求到Action的映射规则 在系列(2)中我们展示了一个简单的get请求,并返回了一个简单的helloworld页面.本篇我们来学习如何来配置一个acti ...