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特性的更多相关文章

  1. Spring事务隔离级别和传播特性

    相信每个人都被问过无数次Spring声明式事务的隔离级别和传播机制吧!今天我也来说说这两个东西. 加入一个小插曲, 一天电话里有人问我声明式事务隔离级别有哪几种, 我就回答了7种, 他问我Spring ...

  2. Spring事务隔离级别和传播特性(转)

    相信每个人都被问过无数次Spring声明式事务的隔离级别和传播机制吧!今天我也来说说这两个东西. 加入一个小插曲,一天电话里有人问我声明式事务隔离级别有哪几种,我就回答了7种,他问我Spring的版本 ...

  3. 【MySQL】事务隔离级别及ACID

    注:begin或start transaction并不是一个事务的起点,而是在执行它们之后的第一个操作InnoDB表的语句,事务才真正开始.start transaction with consist ...

  4. 数据库事务的四大特性以及4种事务的隔离级别-以及对应的5种JDBC事务隔离级别

    本篇讲诉数据库中事务的四大特性(ACID),并且将会详细地说明事务的隔离级别. 如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性: ⑴ 原子性(Atomicity) 原子性是指事务 ...

  5. 【概念原理】四种SQL事务隔离级别和事务ACID特性

    摘要: SQL事务隔离级别和事务的ACID特性 事务是一组读写操作,并且具有只有所有操作都成功才算成功的特性.   事务隔离级别 SQL事务隔离级别由弱到强分别是:READ_UNCOMMITTED.R ...

  6. 什么是事务?事务的四个特性(ACID)?并发事务带来哪些问题?事务隔离级别都有哪些?事务的传播特性

    什么是事务? 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消.也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做. 事物的四个 ...

  7. 事务和JDBC事务隔离级别

    与事务相关的理论 mysql事物隔离级别:http://mj4d.iteye.com/blog/1744276 事务(Transaction): 是并发控制的单元,是用户定义的一个操作序列.这些操作要 ...

  8. 事务、事务特性、事务隔离级别、spring事务传播特性

    事务.事务特性.事务隔离级别.spring事务传播特性   1.什么是事务: 事务是程序中一系列严密的操作,所有操作执行必须成功完成,否则在每个操作所做的更改将会被撤销,这也是事务的原子性(要么成功, ...

  9. 什么是事务、事务特性、事务隔离级别、spring事务传播特性

    1.什么是事务: 事务是程序中一系列严密的操作,所有操作执行必须成功完成,否则在每个操作所做的更改将会被撤销,这也是事务的原子性(要么成功,要么失败). 2.事务特性: 事务特性分为四个:原子性(At ...

随机推荐

  1. C语言 ## __VA_ARGS__ 宏

    在GNU C中,宏可以接受可变数目的参数,就象函数一样 可以把__VA_ARGS__看成是将...赋值给该宏 //注意这里不能在函数中调用abc() #include <stdio.h> ...

  2. CentOS采用grub进 single状态

    当系统文件错误,有可能无法进入系统.或者您忘记了原来的系统password. 用这种方法可以,进single状态,编辑系统启动文件或更改的错误password. 1.重新启动系统. 2.按" ...

  3. 什么时候需要使用Double? double、float、decimal的区别

    原文:什么时候需要使用Double? double.float.decimal的区别 float:浮点型,含字节数为4,32bit,数值范围为-3.4E38~3.4E38(7个有效位) double: ...

  4. 简单DP-艰难取舍

    艰难取舍(seq.cpp/c/pas) [题目描述] 由于hyf长得实在是太帅了,英俊潇洒,风流倜傥,人见人爱,花见花开,车见车载.有一群MM排队看hyf.每个 MM都有自己独特的风格,由于 hyf有 ...

  5. 高速掌握sinox2014激动人心的ZFS和RAID技术

    Sinox2014引入激动人心的zfs系统以及其支持的RAID,让用户高速打造便宜的高可靠性文件server. ZFS文件系统的英文名称为Zettabyte File System,也叫动态文件系统( ...

  6. bootstrap基本标签总结2

    [布局]bootstrap基本标签总结2   缩略图 <div class="container"> <div class="row"> ...

  7. poj3744高速功率矩阵+可能性DP

    Scout YYF I Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4410   Accepted: 1151 Descr ...

  8. Oracleclient+PLSQL Developer实现远程登录Oracle数据库

    Oracle数据库功能强大.性能卓越,在造就这些长处的同一时候,也导致Oracle占内存比較多.针对这个问题,我们怎样做到取其精华去其糟粕呢? 解决方式:我们能够在局域网内的server上安装庞大的O ...

  9. openwrt构建过程探索

    参考网站:http://wiki.openwrt.org/doc/howto/buildroot.exigence 需要下载必要的库文件,编译器等... 1 首先要获得openwrt的源码,参考ope ...

  10. Get Resultset from Oracle Stored procedure

    http://stackoverflow.com/questions/1170548/get-resultset-from-oracle-stored-procedure