SpringBoot学习之事务注解@Transactional
今天学习spring中的事务注解,在学习Spring注解事务之前需要明白一些事务的基本概念:
事务:并发控制的单位,是用户定义的一个操作序列。这些操作要么都做,要么都不做,是一个不可分割的工作单位。通过事务数据库能将逻辑相关的一组操作绑定在一起,以便服务器保持数据的完整性。
事务隔离级别:在并发处理数据中,为了保持数据的完整性和正确性,而执行的操作数据方式。
脏读 :一个事务读取到另一事务未提交的更新数据。
幻读:一个事务读到另一个事务已提交的insert数据。
不可重复读: 是指在一个事务内多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据就有可能不一样的。
Spring事务执行机制:
1.@Transactional:只能被应用到public方法上, 对于其它非public的方法,如果标记了@Transactional也不会报错,但方法没有事务功能.
2.@Transactional:默认情况下遇见RuntimeException类型的异常会执行回滚,Exception类型的异常不执行回滚。
3.@Transactional(rollbackFor=Exception.class) :指定Exception类型的异常进行回滚。
4.@Transactional(noRollbackFor=Exception.class):指定RuntimeException类型不进行回滚。
Spring事务传播行为:
1.@Transactional(propagation=Propagation.REQUIRED) :当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。(这个比较常用)
2.@Transactional(propagation=Propagation.PROPAGATION_SUPPORTS) :当前没有事务,则以非事务方式执行,如果有事务则以事务方式执行。
3.@Transactional(propagation=Propagation.PROPAGATION_MANDATORY) :使用当前的事务,如果当前没有事务,就抛出异常。
4.@Transactional(propagation=Propagation.PROPAGATION_REQUIRES_NEW) :新建事务,如果当前存在事务,把当前事务挂起。
5.@Transactional(propagation=Propagation.PROPAGATION_NOT_SUPPORTED) :以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
6.@Transactional(propagation=Propagation.PROPAGATION_NEVER) :以非事务方式执行,如果当前存在事务,则抛出异常。
7.@Transactional(propagation=Propagation.PROPAGATION_NESTED) :如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类 似的操作。(这个比较常用)
Spring事务隔离级别:
@Transactional(isolation = Isolation.ISOLATION_DEFAULT):这是默认值,表示使用底层数据库的默认隔离级别。对大部分数据库而言,通常这值就是TransactionDefinition.ISOLATION_READ_COMMITTED。
@Transactional(isolation = Isolation.ISOLATION_READ_UNCOMMITTED):该隔离级别表示一个事务可以读取另一个事务修改但还没有提交的数据,该级别不能防止脏读,不可重复读和幻读,因此很少使用该隔离级别。比如PostgreSQL实际上并没有此级别
@Transactional(isolation = Isolation.ISOLATION_READ_COMMITTED):该隔离级别表示一个事务只能读取另一个事务已经提交的数据。该级别可以防止脏读,这也是大多数情况下的推荐值。
@Transactional(isolation = Isolation.ISOLATION_REPEATABLE_READ):该隔离级别表示一个事务在整个过程中可以多次重复执行某个查询,并且每次返回的记录都相同。该级别可以防止脏读和不可重复读。
@Transactional(isolation = Isolation.ISOLATION_SERIALIZABLE):所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。
常用数据库的隔离级别:
MYSQL:默认为REPEATABLE_READ
ORACLE:默认隔离级别是READ_COMMITTED
PostgreSQL:默认隔离级别是READ_COMMITTED