Spring的注解事务行为,通过@Transactional来定制事务行为。
前置:事务有四大特性,ACID
Atomicity:原子性,事务是一个原子性操作,要么全部成功,要么全部失败。
Consistency:一致性,事务操作完成之前,所有的数据要保持一致性。
Isolation:隔离性,事务之间不能相互影响。
Durability:持久性,事务完成后,数据必须持久到数据库中。
isolation,决定了事务的完整性,处理并发事务时可能会出现脏读、不可重复读、幻读
脏读:一个事务读到另一个事务未提交的更新数据。
不可重复读:一个事务两次读同一行数据,但两次读到的数据不一样。(针对update)
幻读:一个事务执行两次查询,但第二次查询比第一次查询多出了一些数据行,同时这个事务丢失了对新增数据行的修改(针对insert)
隔离级别:
READ_UNCOMMITTED:读未提交,在A事务里修改了一条记录,但没有提交事务,但在B事务中读取到了这条修改的记录数据,导致脏读、不可重复读、幻读。
READ_COMMITTED:读已提交,在A事务里修改了一条记录,但没有提交事务,在B事务里读取不到这条修改的记录数据,A事务提交之后,B事务读取到了这条修改的记录数据,解决了脏读,但可导致不可重复读、幻读。
REPEATABLE_READ:可重复读,在READ_COMMITTED基础上,当A事务读取了一条记录,B事务将不允许修改这条记录,解决了脏读、不可重复读,但可导致幻读。
SERIALIZABLE:串行化,此级别下事务是顺序执行的,解决了脏读、不可重复读、幻读,但开销最大。
默认级别:oracle、sql server是READ_COMMITTED,mysql是REPEATABLE_READ。
propagation,定义了事务的生命周期
REQUIRED:方法A调用时没有事务则新建一个事务,当在方法A中调用另外一个方法B的时候,方法B加入到这个事务,方法A和方法B使用同一个事务,如果方法B发生异常需要回滚的时候,整个事务数据回滚。Spring的默认事务传播级别。
REQUIRED_NEW:对于方法A和B,在方法调用的时候无论是否有事务存在都会新建一个新的事务,这样如果在方法A最终调用方法B,A事务挂起,新建B事务,方法B发生异常,不会导致方法A的数据回滚。
NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务,则按REQUIRED属性执行,仅支持DataSourceTransactionManager作为事务管理器。(可做特殊用处,B事务执行出现问题,回滚到某个保存点后,外部捕获异常后执行C事务,在保存点之后继续做其他的事情,很特殊的一个用途)
SUPPORTS:方法调用时有事务就加入到当前事务中,没有事务则以非事务行为进行。
NOT_SUPPORTS:强制方法不在事务中进行,如果存在活动事务,在方法调用开始到执行结束阶段,当前事务都会被挂起。
NEVER:强制方法不在事务中进行,如果存在活动事务,抛出异常。
MANDATORY:强制方法在事务中执行,如果不存在活动事务,抛出异常。
timeout,事务过期时间。
readOnly,指定当前事务是否是只读事务。
rollbackFor,指定哪个或者哪些异常可以引起事务回滚。
noRollbackFor,指定哪个或者哪些异常不可以引起事务回滚。