共计 1805 个字符,预计需要花费 5 分钟才能阅读完成。
当然,Spring 事务回滚的前提是你以后应用的数据库必须反对事务,比方 MySQL 的 Innodb 是反对的,但 Mysaim 则是不反对事务的。
办法一
应用 @Transaction 来配置主动回滚,能够配置在类上,也能够配置在办法上(作用域不同),但对 final 或 private 润饰的办法有效,且该类必须是受 spring 所管控的,也就是被曾经被注入的类,而不是 new 进去的类。
若配置在办法上,则该办法被加上了事务
若配置在类上,则等于给该类的所有办法都加上了该注解。此时如果在该类下的某个办法也加了 @Transaction,则该办法应用本人的配置,其余办法应用类上的配置。
@Service
@Transactional
public class UserServiceImpl implements UserService {
@Override
public void save(User user) {
//some code
//db operation
}
}
复制代码
若被配置的办法或类抛出了异样,则事务会被主动回滚,除非你在该办法中手动捕捉了异样,且没有抛出新的异样。
能够应用 @Transactional(rollbackFor = Exception.class) 来设定针对特定的异样进行事务回滚,如果不设置则默认会回滚 RuntimeException and Error(参考自源码内文档)。
@Service
@Transactional(rollbackFor = Exception.class)
public class UserServiceImpl implements UserService {
@Resource
private UserMapper userMapper;
@Override
public void save(User user) {userMapper.insert(user);
throw new RuntimeException(); // 抛出异样,事务回滚,下面的 insert 插入失败。}
}
复制代码
办法二
通过注入 DataSourceTransactionManager 来手动开启事务,手动回滚事务,用于抛出异样被 catch 后,进行手动回滚,可控水平更高,能够更灵便的应用。
先注入 DataSourceTransactionManager 事务管理对象
new 一个 DefaultTransactionDefinition def = new DefaultTransactionDefinition(); 对象
应用 TransactionStatus status = transactionManager.getTransaction(def); 来开启一个事务,
应用 transactionManager.rollback(status); 来回滚这个事务
应用 transactionManager.commit(status); 来提交这个事务
@Service
public class UserServiceImpl implements UserService {
@Autowired
private DataSourceTransactionManager transactionManager;
@Override
@Transactional
public void save(User user) {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
// explicitly setting the transaction name is something that can only be done programmatically
def.setName("SomeTxName");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = transactionManager.getTransaction(def);
try {
// execute your business logic here
//db operation
} catch (Exception ex) {transactionManager.rollback(status);
throw ex;
}
}
} // 此代码案例来自 Alibaba Coding Guidelines