事务的七种传播行为
看下Transactional注解中Propagation的七种事务的源码
@Transactional(propagation = Propagation.REQUIRED)
public enum Propagation {
/**
* 支持当前事务,如果不存在,则创建一个新事务。
* 其子方法必须运行在一个事务中,如果当前存在事务,会加入到存在的事务中,成为一个整体。
* Support a current transaction, create a new one if none exists.
* Analogous to EJB transaction attribute of the same name.
* <p>This is the default setting of a transaction annotation.
* 在使用REQUIRED时,当其中一个方法报错,会将整个行为回滚;
* 例如需要修改数据库表表数据,只要出现错误,其会全部失败,数据库数据也会回滚;
*/
REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),
/**
* 支持当前事务,如果不存在,以非事务方式执行。
* 当最外围事存在是会继承外围事务,如果没有事务,将以非事务的方式运行
* Support a current transaction, execute non-transactionally if none exists.
* Analogous to EJB transaction attribute of the same name.
* <p>Note: For transaction managers with transaction synchronization,
* {@code SUPPORTS} is slightly different from no transaction at all,
* as it defines a transaction scope that synchronization will apply for.
* As a consequence, the same resources (JDBC Connection, Hibernate Session, etc)
* will be shared for the entire specified scope. Note that this depends on
* the actual synchronization configuration of the transaction manager.
* @see org.springframework.transaction.support.AbstractPlatformTransactionManager#setTransactionSynchronization
*/
SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),
/**
* 该传播属性强制必须存在一个事务,如果不存在,则抛出异常
* Support a current transaction, throw an exception if none exists.
* Analogous to EJB transaction attribute of the same name.
*/
MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),
/**
* Create a new transaction, and suspend the current transaction if one exists.
* Analogous to the EJB transaction attribute of the same name.
* <p><b>NOTE:</b> Actual transaction suspension will not work out-of-the-box
* on all transaction managers. This in particular applies to
* {@link org.springframework.transaction.jta.JtaTransactionManager},
* which requires the {@code javax.transaction.TransactionManager} to be
* made available to it (which is server-specific in standard Java EE).
* @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager
*/
REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),
/**
* 如果当前有事务,则挂起该事务,并且自己创建一个新的事务给自己使用;
* 如果当前没有事务,则同 REQUIRED
*
* Execute non-transactionally, suspend the current transaction if one exists.
* Analogous to EJB transaction attribute of the same name.
* <p><b>NOTE:</b> Actual transaction suspension will not work out-of-the-box
* on all transaction managers. This in particular applies to
* {@link org.springframework.transaction.jta.JtaTransactionManager},
* which requires the {@code javax.transaction.TransactionManager} to be
* made available to it (which is server-specific in standard Java EE).
* @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager
*/
NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),
/**
* 如果当前有事务存在,则抛出异常
* Execute non-transactionally, throw an exception if a transaction exists.
* Analogous to EJB transaction attribute of the same name.
*/
NEVER(TransactionDefinition.PROPAGATION_NEVER),
/**
* 如果当前有事务,则开启子事务(嵌套事务),嵌套事务是独立提交或者回滚;
* 如果当前没有事务,则同 REQUIRED。
* Execute within a nested transaction if a current transaction exists,
* behave like {@code REQUIRED} otherwise. There is no analogous feature in EJB.
* <p>Note: Actual creation of a nested transaction will only work on specific
* transaction managers. Out of the box, this only applies to the JDBC
* DataSourceTransactionManager. Some JTA providers might support nested
* transactions as well.
* @see org.springframework.jdbc.datasource.DataSourceTransactionManager
*/
NESTED(TransactionDefinition.PROPAGATION_NESTED);
总结
1.PROPAGATION_REQUIRED (常用)
- 如果存在当前事务则用当前事务;如果不存在当前事务,就新建一个事务。
- 对操作数据库而言,当其中操作出现错误时,会回滚整个数据库操作。
2.PROPAGATION_SUPPORTS
- 支持当前事务,如果当前没有事务,就以非事务方式执行。具有跟随外围方法的事务,有则有,没有就没有。
3.PROPAGATION_MANDATORY
- 支持当前事务,如果当前没有事务,就抛出异常报错。该传播方式具有强制性,必须存在一个事务。
4.PROPAGATION_REQUIRES_NEW (常用)
- 新建事务,如果当前存在事务,把当前事务挂起。开启一个新事务,新事务执行完毕后,唤醒之前挂起的事务,继续执行。如果不存在当前事务,则新建一个事务。
- 当外围没有事务时,而子方法有实物时,会将两个方法分离开来的,只处理自己的方法。
- 含事务子方法出错时,只会回滚含事务的子方法的数据库操作,无事务的会继续操作。
5.PROPAGATION_NOT_SUPPORTED
- 如果当前有事务,则把事务挂起,自己不使用事务去运行数据库操作
6.PROPAGATION_NEVER
- 以非事务方式执行,如果当前存在事务,则抛出异常。
7.PROPAGATION_NESTED
- 如果当前有事务,则开启子事务(嵌套事务),嵌套事务是独立提交或者回滚;
- 如果当前没有事务,则同 REQUIRED。
- 但是如果主事务提交,则会携带子事务一起提交。
- 如果主事务回滚,则子事务会一起回滚。相反,子事务异常,则父事务可以回滚或不回滚。
Spring事务隔离级别
1) DEFAULT (默认)
- 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别。
- 另外四个与JDBC的隔离级别相对应。比较数据库隔离级别多出的
2) READ_UNCOMMITTED (读未提交)
- 这是事务最低的隔离级别,它允许另外一个事务可以看到这个事务未提交的数据。
- 这种隔离级别会产生脏读,不可重复读和幻像读。
3) READ_COMMITTED (读已提交)
- 保证一个事务修改的数据提交后才能被另外一个事务读取,另外一个事务不能读取该事务未提交的数据。
- 这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻像读。
4) REPEATABLE_READ (可重复读)
- 这种事务隔离级别可以防止脏读、不可重复读,但是可能出现幻像读。
- 它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了不可重复读。
5) SERIALIZABLE(串行化)
- 这是花费最高代价但是最可靠的事务隔离级别,事务被处理为顺序执行。
- 除了防止脏读、不可重复读外,还避免了幻像读。
本文详细解析了Java中Spring框架事务管理的七种传播行为,包括REQUIRED、SUPPORTS等,并介绍了五种不同的事务隔离级别及其应用场景。
1043

被折叠的 条评论
为什么被折叠?



