Spring的事务管理

代码中处理事务一般都在Service层,也就是业务逻辑层。

而在spring中通常使用两种方式实现事务

​ 1,使用spring的事务注解管理事务;使用@Transaction注解完成事务的控制,此注解可以放到类上和方法上,控制和放的位置相对应;类上的事务管理所有的方法。

​ 2,使用AspectJ的AOP配置管理事务,也叫做声明式事务管理;只需要在配置文件中设置整个项目即遵循这套事务的配置设定。

Spring事务的五大隔离级别

DEFAULT (默认)

​ 是PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别

READ_UNCOMMINTTED (读未提交)

​ 事务的最低隔离级别,它允许另一个事务可以看到这个事务未提交的数据。从而产生脏读,不可重复读和幻读。

READ_COMMINTTED (读已提交)

​ 保证一个事务修改的数据提交后才能被另一个事务读取,另外一个事务部不能读取该事物未提交的数据;这种事务隔离级别可以避免脏读,但是不能避免不可重复读和幻读。

REPEATABLE_READ (可重复读)

​ 可以防止幻读,不可重复度,但是可能出现幻读;它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了不可重复读。

SERIALIZABLE (串行化)

​ 串行化是花费代价最高的隔离级别,事务被处理为顺序执行。可以避免其他事务所有的问题;防止脏读,重复读,幻读;

它每次都需要重新获得表级共享锁,读写相互都会阻塞。

我们常用的MySQL的默认隔离级别是REPEATABLE_READ 可重复读;

Spring事务的传播行为

PROPAGATION_MANDATORY

​ 表示该方法必须运行在一个事务中,如果当前没有事务正在发生,将抛出一个异常

PROPAGATION_NESTED

​ 表示当前如果有一个事务正在进行中,则该方法应当运行在一个嵌套的事务中,被嵌套的事务可以独立封装事务进行提交或回滚,如果封装事务不存在,行为就像PROPAGATION_REQUIRES一样

PROPAGATION_NRVER

表示当前的方法不应该在一个事务中运行,如果一个事务正在进行,则会抛出一个异常。

PROPAGETION_NOT_SUPPORTED

表示改方法不应该在一个事务中运行,如果一个现有事务正在进行中,他将会在改方法的运行期间被挂起;

PROPAGETION_SUPPORTS

表示当前方法不需要事务性上下文,但是如果有一个事务已经事务在运行的话,他也可以在这个事务里运行

PROPAGETION_REQUIRES_NEW

表示当前方法必须在他自己的事务里运行,一个新的事务将被启动,而且如果有一个现有事务在在运行的话,则将这个方法运行期间被挂起;

PROPAGETION_REQUIRES

表示当前方法必须在一个事务中运行,如果一个现有事务正在运行中,该方法将在那个事务中运行,否则就要开始一个新的事务

@Transactional

 @Transactional(
   						//事务的传播特性
   						propagation = Propagation.REQUIRED,
   						//指定发生什么异常不回滚(使用的是异常的名称)
               noRollbackForClassName = "ArithmeticException", 
  					 	//指定发生什么异常不回滚(使用的是异常的类型)
               noRollbackFor = ArithmeticException.class,
   						//指定发生什么异常必须回滚(使用的是异常的名称)
               rollbackForClassName = "",
   						//指定发生什么异常必须回滚(使用的是异常的类型)
               rollbackFor = ArithmeticException.class,
    					//连接超时设置,默认值是-1,表示永不超时
               timeout = -1,
   						//默认是false,如果是查询操作,必须设置为true.
               readOnly = false, 
   						//使用数据库自已的隔离级别  
               isolation = Isolation.DEFAULT      
               )