小小小小涛

事务理解及Spring中的事务

一、隔离级别理解

1.脏读

首先理解,一个事务对数据进行了改变,尽管该事务尚未提交,但此时其他事务中的查询语句(注意一定是处于事务中的语句,不处于事务中的语句查到的是正常的)查到的数据,是该事务修改之后的。验证如下:

一张简单的user表

我们运行下面的语句123三行,开启事务,但是尚未提交

我们可以看到即使该事务尚未提交,但是此时查到的也是事务修改后的数据。

再看,运行如下56两行语句

所以,脏读,就是一个事务B读到的数据是另外一个事务A尚未提交的数据,这种情况称为脏读,因为如果A事务回滚了,那么B事务读取到的数据就是不正确的数据。

 2.不可重复读取

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

3.幻读

事务A对表中符合条件的条数据进行了修改,此时事务B又插入了一条符合条件的数据并且提交给数据库了,那么如果此时事务A再去查看刚才的修改结果,发现还有一条数据没有被修改,或者A事务查询符合条件的数据,发现10条,此时B事务删除或插入了一条符合条件的数据,那A事务再查,发现结果为9条或者11条,出现了幻觉,这种情况就是幻读,也称虚读。

 

不可重复读取和幻读都是读取了已提交的事务操作过的数据,而脏读是读取了未提交的事务操作的数据。

二、Spring中的事务处理

Spring对事务提供了很好的支持,我们来看看spring中的事务处理方式

1.传播属性

PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。

PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。

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

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

PROPAGATION_NESTED---新建事务,如果当前存在事务,把当前事务挂起。与PROPAGATION_REQUIRES_NEW的区别是父事务回滚,则子事务也需要回滚。

2.隔离级别

DEFAULT (默认)
这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.另外四个与JDBC的隔离级别相对应


READ_UNCOMMITTED (读未提交)
这是事务最低的隔离级别,它允许另外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。

READ_COMMITTED (读已提交)
保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻像读,这种方式是最常用的级别。

REPEATABLE_READ (可重复读)
保证事务不会修改已被其他事务读取但事务尚未提交或回滚的数据。这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了不可重复读 ,但是资源消耗较大。

SERIALIZABLE(串行化)
这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻像读。此种方式资源消耗最大。

posted on 2017-03-10 16:58  小小小小涛  阅读(211)  评论(0编辑  收藏  举报

导航