事务管理在系统开发中是不可缺少的一部分,Spring提供了很好事务管理机制,主要分为编程式事务和声明式事务两种。
一、声明式事务
在业务逻辑层接口的实现类中的相关方法上声明事物
@Transactional
@Override
public String interfaceTest(Map<String, Object> map) {
// 事务的操作
return null;
}
Transactional 注解的常用属性表:
二、编程式事务
/**
* 注入
*/
@Autowired
private DataSourceTransactionManager transactionManager;
@Override
public String interfaceTest(Map<String, Object> map) {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
// 设置事务名称
def.setName("test-Transactional");
// 读写或只读事务、默认:读写
def.setReadOnly(true);
// 事务超时时间,默认:不超时 单位:秒
def.setTimeout(10);
/**
* 设置事务的隔离级别
*
* 1、TransactionDefinition.ISOLATION_DEFAULT
* 这是一个默认的隔离级别,默认使用数据库的隔离级别。
* 2、TransactionDefinition.ISOLATION_READ_UNCOMMITTED
* 这是事务最低的隔离界别,他允许别的事务可以看到这个事务未提交的数据。
* 这种隔离级别可能会产生脏读,不可重复读和幻像读。
* 3、TransactionDefinition.ISOLATION_READ_COMMITTED
* 这个级别可以保证在数据提交以后才能被另个一个事务读取。
* 这种隔离级别可以避免脏读,但是可能会出现不可重复读和幻读。
* 4、TransactionDefinition.ISOLATION_REPEATABLE_READ
* 这个级别可以禁止一个事务读取一个没有提交变化的行。
* 这种隔离级别可以防止脏读和不可重复读,但是可能会出现幻读。
* 5、TransactionDefinition.ISOLATION_SERIALIZABLE
* 这种隔离级别可以防止脏读、不可重复读、幻读。
*
*/
def.setIsolationLevel(TransactionDefinition.ISOLATION_DEFAULT);
/**
* 设置事务的传播行为
*
* 1、TransactionDefinition.PROPAGATION_REQUIRED
* 如果当前存在事务,则加入该事务,如果当前没有事务,则创建一个新的事务。默认值
* 2、TransactionDefinition.PROPAGATION_REQUIRES_NEW
* 创建一个新的事务,如果当前存在事务,则把当前的事务挂起。
* 3、TransactionDefinition.PROPAGATION_SUPPORTS
* 如果当前存在事务,则加入该事务,如果当前没有事务,则以非事务的方式继续运行。
* 4、TransactionDefinition.PROPAGATION_NOT_SUPPORTED
* 以非事务方式运行,如果当前存在事务,则把当前事务挂起。
* 5、TransactionDefinition.PROPAGATION_NEVER
* 以非事务方式运行,如果当前存在事务,则抛出异常。
* 6、TransactionDefinition.PROPAGATION_MANDATORY
* 如果当前存在事务、则加入该事务,如果当前没有事务,则抛出异常
* 7、TransactionDefinition.PROPAGATION_NESTED
* 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行。
* 如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。
*/
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus transactionStatus = transactionManager.getTransaction(def);
try {
//
// 提交事务
transactionManager.commit(transactionStatus);
}catch (Exception e){
// 回滚事务
transactionManager.rollback(transactionStatus);
}
return null;
}
三、对比
声明式事务管理方法只需要增加@Transactional注解即可,不需要依赖底层API进行编码。
声明事务管理就是使用 AOP 实现的,本质就是通过对目标方法执行前后进行拦截。
以下几种场景就可能导致声明式事务失效:
1、@Transactional 应用在非 public 修饰的方法上。
2、@Transactional 注解属性 propagation 设置错误
3、@Transactional 注解属性 rollbackFor 设置错误
4、同一类中方法调用,导致@Transactional 失效。
5、异常被catch捕获,导致@Transactional 失效。
6、数据库引擎不支持事务。
以上几个问题,如果使用编程式事务的话,很多都是可以避免的。
阿里巴巴规约中也提到过:
打赏
当前共有 0 条评论