一、背景
Mysql在修改完数据后,默认会自动触发事务Commit提交。
而在我们服务的一个方法里,需要多次修改Mysql记录。
为了保证原子性,我们需要将Mysql设为手动提交,多次修改后再commit提交。
二、Spring事务
1、编程式事务管理
TransactionTemplate三组件 | |
---|---|
PlatformTransactionManager | 事务管理器,用于管理事务的开始、提交和回滚。 |
TransactionDefinition | 事务定义,用于定义事务的隔离级别、超时时间、只读等。 |
TransactionCallback | 事务回调,用于执行具体的业务逻辑。 |
使用1
private TransactionTemplate transactionTemplate;public void MyTransaction() {transactionTemplate.execute((status -> {try {//todoreturn null;} catch (Exception e){status.setRollbackOnly();}return null;}));}
使用2
@Autowired
private PlatformTransactionManager transactionManager;public void testTransaction() {TransactionStatus transactionStatus = transactionManager.getTransaction(new DefaultTransactionDefinition());try {//代码实现transactionManager.commit(transactionStatus);} catch (Exception e) {transactionManager.rollback(transactionStatus);}
}
2、声明式事务管理
@Transactional
标注位置
- 标注在方法上,它会在方法执行期间开启一个新的事务。如果方法成功完成,则提交事务。如果方法抛出异常,则回滚事务。
- 标注在类上时,它会应用于类中的所有公共方法,并且可以通过在方法上指定propagation属性来覆盖类级别的行为。
属性
- propagation : 事务传播行为
- isolation :事务隔离级别
- timeout :定义事务的超时时间(单位为秒)。默认值为-1,表示使用数据库的默认超时时间。
- readOnly:是否只读。默认值为false,表示允许读写操作。如果设置为true,则只允许读操作。
- rollbackFor:指定哪些异常需要回滚事务。默认值为RuntimeException和Error。可以指定其他异常,并且可以指定多种异常,例如rollbackFor={SQLException.class,MyException.class}。
@Transactional(propagation = Propagation.REQUIRED)
public void MyMethod {//你的业务代码
}
三、Spring事务传播机制
假如我们的事务方法,修改了某些数据。
但是!!!里面还调用了另一个事务方法,那该怎么处理???
我们是要将当它们当成一个事务?还是两个事务??
Spring提供了七种策略,可以让我们去选择。
Spring提供了七种策略(事务传播机制 )
事务的传播机制 | |
---|---|
PROPAGATION_REQUIRED | 支持当前事务,如果当前没有事务,就新建一个事务。(默认)。 |
PROPAGATION_SUPPORTS | 支持当前事务,如果当前没有事务,就以非事务方式执行。 |
PROPAGATION_MANDATORY | 支持当前事务,如果当前没有事务,就抛出异常。 |
PROPAGATION_REQUIRES_NEW | 新建事务,如果当前存在事务,把当前事务挂起。 |
PROPAGATION_NOT_SUPPORTED | 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 |
PROPAGATION_NEVER | 以非事务方式执行,如果当前存在事务,则抛出异常。 |
PROPAGATION_NESTED | 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。 |