事务控制
@Transactional注解参数说明
事务传播行为种类:Spring
在TransactionDefinition
接口中规定了7种类型的事务传播行为,**它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播。 使用示例:@Transactional(propagation=Propagation.REQUIRED)
事务传播行为类型 | 说明 |
---|---|
PROPAGATION_REQUIRED | 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。 |
PROPAGATION_SUPPORTS | 支持当前事务,如果当前没有事务,就以非事务方式执行。 |
PROPAGATION_MANDATORY | 使用当前的事务,如果当前没有事务,就抛出异常。 |
PROPAGATION_REQUIRES_NEW | 新建事务,如果当前存在事务,把当前事务挂起。 |
PROPAGATION_NOT_SUPPORTED | 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 |
PROPAGATION_NEVER | 以非事务方式执行,如果当前存在事务,则抛出异常。 |
PROPAGATION_NESTED | 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类 似的操作。 |
@Transactional注解失效原因排查
- @Transactional 加于private方法,无效
- @Transactional 加于未加入接口的public方法, 无效
- @Transactional 加于未加入接口的public方法,再通过普通接口方法调用,无效
- @Transactional 加于接口方法后,无论下面调用的是private或public方法,都有效
- @Transactional 加于接口方法后,被本类普通接口方法直接调用,无效
- @Transactional 加于接口方法后,被本类普通接口方法通过接口调用,有效
- @Transactional 加于接口方法后,被它类的接口方法调用,有效
- @Transactional 加于接口方法后,被它类的私有方法调用后,有效
- 方法捕获异常但没抛出异常,无效
失效原因说明
@Transactional
失效的背后其实就是Spring
代理机制造成的。通俗点说就是我们现在都不用去new
对象了,而是把对象交给Spring
去管理,既然交给Spring
去管理,那就要按照Spring
的方式去使用。 Spring
是什么方式管理?它会把你注入的对象都转换成Bean
,这个Bean
是被修饰过的代理类,它和new
出来的对象不一样。 为什么this.xxxxx()
会失效?因为this
调用是java的方式,它并不是Spring的调用方式。
手动事务/编程式事务
方式一
java
//这个类在配数据源的时候要配置
@Autowired
DataSourceTransactionManager dataSourceTransactionManager;
@Autowired
TransactionDefinition transactionDefinition;
//开启手动事务
TransactionStatus transactionStatus = null;
try {
transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
//批量插入
workProMapper.insertBatchInterruptData(batchList);
dataSourceTransactionManager.commit(transactionStatus);//提交
}catch (Exception e){
e.printStackTrace();
log.error(e.getMessage(),e);//记录日志
dataSourceTransactionManager.rollback(transactionStatus);//回滚
}
方式二
java
@Autowired
private TransactionTemplate transactionTemplate;
public void performTransactionalOperation() {
//execute方法是被try catch包裹的,自动做了开启事务和回滚事务
transactionTemplate.execute(new TransactionCallback<Void>() {
public Void doInTransaction(TransactionStatus status) {
//在这里执行数据库操作
return null;
}
});
}