持续创造,加速成长!这是我参与「日新方案 10 月更文挑战」的第30天,点击查看活动详情


当然,Spring业务回滚的条件是你当前运用的数据库有必要支撑业务,比如MySQL的Innodb是支撑的,但Mysaim则是不支撑业务的。

办法一

  1. 运用 @Transaction 来装备自动回滚,能够装备在类上,也能够装备在办法上(作用域不同),但对final或private润饰的办法无效,且该类有必要是受spring所管控的,也便是被已经被注入的类,而不是new出来的类。

    • 若装备在办法上,则该办法被加上了业务
    • 若装备在类上,则等于给该类的一切办法都加上了该注解。此时假如在该类下的某个办法也加了 @Transaction ,则该办法运用自己的装备,其他办法运用类上的装备。
    @Service
    @Transactional
    public class UserServiceImpl implements UserService {
        @Override
        public void save(User user) {
            //some code
            //db operation
        }
    }
    
  2. 若被装备的办法或类抛出了反常,则业务会被自动回滚,除非你在该办法中手动捕获了反常,且没有抛出新的反常。

    能够运用 @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后,进行手动回滚,可控程度更高,能够更灵敏的运用。

  1. 先注入 DataSourceTransactionManager 业务管理对象
  2. new 一个 DefaultTransactionDefinition def = new DefaultTransactionDefinition(); 对象
  3. 运用 TransactionStatus status = transactionManager.getTransaction(def);来敞开一个业务,
  4. 运用 transactionManager.rollback(status); 来回滚这个业务
  5. 运用 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