一. 概述
在java开发中我们经常用到@Transactional进行事务处理, 但往往有时候会发现事务不生效, 这是它的一个代理机制造成的, 今天我们来说说几个事务失效的场景及手动设置事务方法
二. 事务失效场景
1.@Transactional作用在类上, 非public方法事务会失效
- 对非public方法进行事务注解。@Transactional 将会失效。
- Transactional 事务配置属性中的propagation 属性配置的问题。
- 业务代码被try{}catch(){}了, 这种是最容易犯错的
三. 手动设置事务回滚
3.1 方式一
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
@Service
public class MyService {
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
private PlatformTransactionManager transactionManager;
public void executeMultipleSqlWithManualTransaction() {
DefaultTransactionDefinition def = new DefaultTransactionDefinition(); // 创建默认的事务定义对象
TransactionStatus status = transactionManager.getTransaction(def); // 获取事务状态
try {
String sql1 = "INSERT INTO table_name (column1) VALUES ('value1')";
String sql2 = "UPDATE table_name SET column2='new value' WHERE condition";
jdbcTemplate.update(sql1); // 执行第一条SQL语句
jdbcTemplate.update(sql2); // 执行第二条SQL语句
transactionManager.commit(status); // 提交事务
} catch (Exception e) {
transactionManager.rollback(status); // 发生异常时回滚事务
throw e;
} finally {
if (!status.isCompleted()) {
transactionManager.rollback(status); // 若未完成则进行回滚操作
}
}
}
}
3.2 方式二
@Transactional //事务的注解
public class UserServiceImpl implements UserService{
@Autowired
UserMapper userMapper;
@Override
public void updateUser(User user) throws Exception {
try {
userMapper.updateUser(user);
} catch (Exception e) {
//强制手动事务回滚
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}
}
了解更多事务的机制请前往->Spring-事务机制
四. 事务提交后操作
@Transactional //事务的注解
public class UserServiceImpl implements UserService{
@Autowired
UserMapper userMapper;
@Override
public void updateUser(User user) throws Exception {
userMapper.updateUser(user);
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
@Override
public void afterCommit() {
// 事务提交后操作
}
});
}
}