@Transactional使用

转:https://www.jianshu.com/p/9098372c108a
@Transactional(rollbackFor)

概括
@Transactional注解有两个,一个是spring提供的@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中间接调用的方法不会触发事务,具体可以看下这篇文章https://zhuanlan.zhihu.com/p/38208248 ,感谢作者的详细讲述。

你可能感兴趣的:(java)