当然,Spring事务回滚的前提是你以后应用的数据库必须反对事务,比方MySQL的Innodb是反对的,但Mysaim则是不反对事务的。
办法一
应用 @Transaction 来配置主动回滚,能够配置在类上,也能够配置在办法上(作用域不同),但对final或private润饰的办法有效,且该类必须是受spring所管控的,也就是被曾经被注入的类,而不是new进去的类。
若配置在办法上,则该办法被加上了事务
若配置在类上,则等于给该类的所有办法都加上了该注解。此时如果在该类下的某个办法也加了 @Transaction ,则该办法应用本人的配置,其余办法应用类上的配置。
@Service
@Transactional
public class UserServiceImpl implements UserService {
@Overridepublic 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 {
@Resourceprivate UserMapper userMapper;@Overridepublic 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