Spring事物隔离级别及事物传播行为@Transactional实现

阅读本篇文章前,请先阅读以下文章:html

四种事物隔离级别详解

 

先看下@Transactional能够配制那些参数及以其所表明的意义。spring

isolation数据库

枚举org.springframework.transaction.annotation.Isolation的值并发

事务隔离级别post

noRollbackFor性能

Class<? extends Throwable>[]url

一组异常类,遇到时不回滚。默认为{}spa

noRollbackForClassNamehtm

Stirng[]blog

一组异常类名,遇到时不回滚,默认为{}

propagation

枚举org.springframework.transaction.annotation.Propagation的值

事务传播行为

readOnly

boolean

事务读写性

rollbackFor

Class<? extends Throwable>[]

一组异常类,遇到时回滚

rollbackForClassName

Stirng[]

一组异常类名,遇到时回滚

timeout

 

超时时间,以秒为单位

value

String

可选的限定描述符,指定使用的事务管理器

 


isolation事务隔离级别,使用时通常以下。

@Transactional(isolation=Isolation.DEFAULT)

public void method(){}

 

isolation的参数有如下五种:

1_一、Isolation.DEFAULT:为数据源的默认隔离级别

1_二、isolation=Isolation.READ_UNCOMMITTED:未受权读取级别

以操做同一行数据为前提,读事务容许其余读事务和写事务,未提交的写事务禁止其余写事务(但容许其余读事务)。此隔离级别能够防止更新丢失,但不能防止脏读、不可重复读、幻读。此隔离级别能够经过“排他写锁”实现。

1_三、iIsolation.READ_COMMITTED:受权读取级别

以操做同一行数据为前提,读事务容许其余读事务和写事务,未提交的写事务禁止其余读事务和写事务。此隔离级别能够防止更新丢失、脏读,但不能防止不可重复读、幻读。此隔离级别能够经过“瞬间共享读锁”和“排他写锁”实现。

1_四、iIsolation.REPEATABLE_READ:可重复读取级别

以操做同一行数据为前提,读事务禁止其余写事务(但容许其余读事务),未提交的写事务禁止其余读事务和写事务。此隔离级别能够防止更新丢失、脏读、不可重复读,但不能防止幻读。此隔离级别能够经过“共享读锁”和“排他写锁”实现。

1_五、iIsolation.SERIALIZABLE:序列化级别

提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,不能并发执行。此隔离级别能够防止更新丢失、脏读、不可重复读、幻读。若是仅仅经过“行级锁”是没法实现事务序列化的,必须经过其余机制保证新插入的数据不会被刚执行查询操做的事务访问到。

隔离级别越高,越能保证数据的完整性和一致性,可是对并发性能的影响也越大。对于多数应用程序,能够优先考虑把数据库系统的隔离级别设为Read Committed。它可以避免更新丢失、脏读,并且具备较好的并发性能。尽管它会致使不可重复读、幻读这些并发问题,在可能出现这类问题的个别场合,能够由应用程序采用悲观锁或乐观锁来控制。

有关事务的关键字说明以下,说明以下:

 

原子性(Atomicity):

事务是数据库的逻辑工做单位,它对数据库的修改要么所有执行,要么所有不执行。

一致性(Consistemcy):

事务先后,数据库的状态都知足全部的完整性约束。

隔离性(Isolation):

并发执行的事务是隔离的,一个不影响一个。若是有两个事务,运行在相同的时间内,执行相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操做间的混淆,必须串行化或序列化请求,使得在同一时间仅有一个请求用于同一数据。经过设置数据库的隔离级别,能够达到不一样的隔离效果。

持久性(Durability):

在事务完成之后,该事务所对数据库所做的更改便持久的保存在数据库之中,并不会被回滚。

更新丢失:

两个事务都同时更新一行数据,可是第二个事务却中途失败退出,致使对数据的两个修改都失效了。这是由于系统没有执行任何的锁操做,所以并发事务并无被隔离开来。

脏读:

脏读又称无效数据读出。一个事务读取另一个事务尚未提交的数据叫脏读。

例如:事务T1修改了一行数据,可是尚未提交,这时候事务T2读取了被事务T1修改后的数据,以后事务T1由于某种缘由Rollback了,那么事务T2读取的数据就是脏的。

不可重复读:

不可重复读是指在同一个事务内,两个相同的查询返回了不一样的结果。

例如:事务T1读取某一数据,事务T2读取并修改了该数据,T1为了对读取值进行检验而再次读取该数据,便获得了不一样的结果。

幻读:

事务在操做过程当中进行两次查询,第二次查询的结果包含了第一次查询中未出现的数据或者缺乏了第一次查询中出现的数据

例如:系统管理员A将数据库中全部学生的成绩从具体分数改成ABCDE等级,可是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉同样。这就叫幻读。

以上的4种问题(更新丢失、脏读、不可重复读、幻读)都和事务的隔离级别有关。经过设置事务的隔离级别,能够避免上述问题的发生。

事物传播行为介绍:

  @Transactional(propagation=Propagation.REQUIRED) :若是有事务, 那么加入事务, 没有的话新建一个(默认状况下)
  @Transactional(propagation=Propagation.NOT_SUPPORTED) :容器不为这个方法开启事务
  @Transactional(propagation=Propagation.REQUIRES_NEW) :不论是否存在事务,都建立一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务
  @Transactional(propagation=Propagation.MANDATORY) :必须在一个已有的事务中执行,不然抛出异常
  @Transactional(propagation=Propagation.NEVER) :必须在一个没有的事务中执行,不然抛出异常(与Propagation.MANDATORY相反)
  @Transactional(propagation=Propagation.SUPPORTS) :若是其余bean调用这个方法,在其余bean中声明事务,那就用事务.若是其余bean没有声明事务,那就不用事务.

 

事物超时设置:

  @Transactional(timeout=30) //默认是30秒

 

事务隔离级别:

  @Transactional(isolation = Isolation.READ_UNCOMMITTED):读取未提交数据(会出现脏读, 不可重复读) 基本不使用
  @Transactional(isolation = Isolation.READ_COMMITTED):读取已提交数据(会出现不可重复读和幻读)
  @Transactional(isolation = Isolation.REPEATABLE_READ):可重复读(会出现幻读)
  @Transactional(isolation = Isolation.SERIALIZABLE):串行化

  MYSQL: 默认为REPEATABLE_READ级别

  SQLSERVER: 默认为READ_COMMITTED

  Oracle 默认隔离级别 READ_COMMITTED

相关文章
相关标签/搜索