持续创造,加速成长!这是我参与「日新方案 10 月更文挑战」的第30天,点击查看活动详情
当然,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