数据库事务的特性、隔离级别以及传播行为

数据库事务的特性、隔离级别以及传播行为


事务是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。


一、事务四种特性


1、原子性

事务所包含的操作,要么全部提交,要么全部回滚。事务若成功必须全部应用到数据库,若失败则不能对数据库产生任何影响。

2、一致性

事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。

拿转账来说,假设用户a和用户b两只的钱加起来一共是5000,那么不管a和b之间如何转账,转几次账,事务结束后两个用户的钱加起来应该还得是500,这就是事务的一致性。

3、隔离性

隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要互相隔离。

对于任意两个事务a b,在a看来,b要么在a开始之间结束,要么在a结束之后开始。

4、持久性

是指一个事务一但被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。


二、隔离级别


1、脏读是指:一个事务处理过程中读取了另一个未提交的事务中的数据。

2、不可重复读是指:一个事务读取了前一个事务提交的数据;在数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据的值,这是由于在查询间隔,被另一个事务修改并提交了。

3、幻读是指:事务非独立执行时发生的一种现象。例如事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读。

 

Sericlizable(串行化): 可避免脏读、不可重复读、幻读的发生。(这个级别可能导致大量超时现象和锁竞争)

Repeatable read(可重复读):可避免脏读、不可重复读脏读。

Read committed(读已提交):可避免脏读脏读。

Read uncommitted(读未提交):最低级别,任何状况都无法保证。

mysql数据库中,支持以上四种隔离级别,默认Repeatable read;在oracle书库中支持SerializableRead committed,默认Read committed

mysql中查询隔离级别:select @@tx_isolation;

修改隔离级别:set transaction isolation level repeatable read;

或:set tx_isolation='repeatable-read';

启动事务:start transaction;

设置数据库的隔离级别一定要是在开启事务之前;

如果是使用JDBC对数据库的事务设置隔离级别的话,也应该是在调用Connection对象的setAutoCommit(false)方法之前。调用Connection对象的setTransactionIsolation(level)即可设置当前链接的隔离级别,至于参数level,可以使用Connection对象的字段:

隔离级别的设置只对当前链接有效。对于使用MySQL命令窗口而言,一个窗口就相当于一个链接,当前窗口设置的隔离级别只对当前窗口中的事务有效;对于JDBC操作数据库来说,一个Connection对象相当于一个链接,而对于Connection对象设置的隔离级别只对该Connection对象有效,与其他链接Connection对象无关。


三、事务传播行为类型


1PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就假如该事务,该设置是最常用的设置。

2PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。

3PROPAGATION_MANDTORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。

4PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。

新事务不依赖于外部事务。

5PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把事务挂起。

6PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。

7PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

挂起:例如 方法A支持事务,方法B不支持事务,方法A调用方法B
在方法A开始运行时,系统为它建立Transaction,方法A中对于数据库的处理操作,会在该Transaction的控制之下。
这时,方法A调用方法B,方法A打开的Transaction将挂起,方法B中任何数据库操作,都不在该Transaction的管理之下。
当方法B返回,方法A继续运行,之前的Transaction回复,后面的数据库操作继续在该Transaction的控制之下 提交或回滚。

嵌套事务:我理解是外部事务的子事务,属于外部事务的一部分,子事务回滚只针对自己。子事务全部commit并且外部事务成功的情况下,才可以将整个事务commit,倘若有一个子事务没有commit,则整个事务rollback。


参考:http://blog.csdn.net/shuaihj/article/details/14163713

参考:http://www.cnblogs.com/fjdingsd/p/5273008.html#3794250

参考:http://www.cnblogs.com/hq-123/p/6023359.html

参考:https://zhidao.baidu.com/question/109536055.html

参考:http://www.cnblogs.com/wzhanke/p/4878851.html

猜你喜欢

转载自blog.csdn.net/xiaopingga/article/details/78189521
今日推荐