@org.springframework.transaction.annotation.Transactional
另一个是jdk提供@javax.transaction.Transactional
。在回滚的设置上,spring提供的是rollbackFor
,jdk提供的是rollbackOn
,在使用方法上是一致的。这两个注解在我有限的测试里表现是一样的。
用在哪里
@Transactional
注解既可以写在方法上也可以写在类上。写在类上则这个类的所有public方法都将会有事务。这样显然会使一些不需要事务的方法产生事务,所以更好的做法是在想要添加事务的方法上标注@Transactional
。
rollbackFor
@Transactional
的rollbackFor用于指定能够触发事务回滚的异常类型,可以指定多个,用逗号分隔。rollbackFor
默认值为UncheckedException,包括了RuntimeException和Error.
当我们直接使用@Transactional
不指定rollbackFor
时,Exception及其子类都不会触发回滚。
public class BusinessException extends Exception { public BusinessException(String msg) { super(msg); } }
@Autowired private UserRepository userRepository; // 不回滚 @Transactional public void test1() throws Exception { User user = new User(1, "15000000000", "d243ewa", "Comma"); saveUser(user); throw new Exception("test1 error"); } // 不回滚 @Transactional public void test11() throws Exception { User user = new User(1, "15000000000", "d243ewa", "Comma"); saveUser(user); throw new BusinessException("test11 error"); } // 回滚 @Transactional(rollbackOn = Exception.class) public void test2() throws Exception { User user = new User(1, "15000000000", "d243ewa", "Comma"); saveUser(user); throw new Exception("test2 error"); } // 回滚 @Transactional(rollbackOn = Exception.class) public void test21() throws Exception { User user = new User(1, "15000000000", "d243ewa", "Comma"); saveUser(user); throw new BusinessException("test21 error"); } // 回滚 @Transactional public void test3() { User user = new User(1, "15000000000", "d243ewa", "Comma"); saveUser(user); throw new RuntimeException("test3 runtime error"); } // 不回滚 @Transactional public void test4() throws Exception { User user = new User(1, "15000000000", "d243ewa", "Comma"); test41(user); throw new Exception("test4 error"); } @Transactional(rollbackOn = Exception.class) public void test41(User user) { saveUser(user); } // 不回滚 public void test5() throws BusinessException { test6(); } // 回滚 @Transactional(rollbackOn = Exception.class) public void test6() throws BusinessException { User user = new User(1, "15000000000", "d243ewa", "Comma"); saveUser(user); throw new BusinessException("test6 error"); } // 回滚 @Transactional(rollbackOn = Exception.class) public void test7() throws BusinessException { test8(); } public void test8() throws BusinessException { User user = new User(1, "15000000000", "d243ewa", "Comma"); saveUser(user); throw new BusinessException("test8 error"); } public User saveUser(User user) { return userRepository.save(user); }
有一点需要注意,在service中间接调用的方法不会触发事务