传播行为当前有事务当前无事务异常回滚范围
REQUIRED加入事务新建事务整个事务
SUPPORTS加入事务非事务运行事务内操作
MANDATORY加入事务抛异常整个事务
REQUIRES_NEW新建事务新建事务仅新事务
NOT_SUPPORTED挂起事务,非事务运行非事务运行
NEVER抛异常非事务运行
NESTED嵌套事务(保存点)新建事务嵌套事务内

注意方法A调用有事务的方法B,需要用Spring 的代理对象,不然事务不生效。因为@Transactional底层是通过代理类实现事务的。

都是对于内部方法来说:
REQUIRED
    内外层方法用相同的事务,同时提交和回滚
REQUIRES_NEW
    内层独立事务,各自提交不影响
NESTED
    内层方法有独立的存档点,内部抛异常指挥回滚到内部方法的开始状态,不会回滚外部的方法

不常用的:
SUPPORTS 外部有事务,那就用同一个事务,即使外部捕捉异常,也会回滚
NOT_SUPPORTED:内部方法报错,外部事务不会回滚,
MANDATORY 内外同一个事务,需要检查外部事务有事务,没有就会报错回滚(外部捕捉了异常,也会回滚)
NEVER 外部有事务,内部方法用事务会报错,外部事务回滚(如果外部吃掉异常,外部事务就不会回滚)

测试代码:

/**
 * 都是对于内部方法来说:
 * REQUIRED
 * 内外层方法用相同的事务,同时提交和回滚
 * REQUIRES_NEW
 * 内层独立事务,各自提交不影响
 * NESTED
 * 内层方法有独立的存档点,内部抛异常指挥回滚到内部方法的开始状态,不会回滚外部的方法
 *
 * 不常用的:
 * SUPPORTS 外部有事务,那就用同一个事务,即使外部捕捉异常,也会回滚
 * NOT_SUPPORTED:内部方法报错,外部事务不会回滚,
 * MANDATORY 内外同一个事务,需要检查外部事务有事务,没有就会报错回滚(外部捕捉了异常,也会回滚)
 * NEVER 外部有事务,内部方法用事务会报错,外部事务回滚(如果外部吃掉异常,外部事务就不会回滚)
 *
 */

@Override
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public String trans() {
    Book book = new Book();
    book.setId(10);
    book.setName("test");
    boolean save = save(book);
    log.info(save + "");

    BookServiceImpl bookService = (BookServiceImpl) AopContext.currentProxy();

    try {
        bookService.otherTrans(10);
    } catch (Exception e) {

    }

    return "ok";
}

@Transactional(propagation = Propagation.SUPPORTS)
public void otherTrans(int i) {
    Book book = new Book();
    book.setId(20 + i);
    book.setName("otherTrans" + i);
    save(book);

    int a = 100 / 0;
}

// Propagation.NESTED 测试
@Override
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public String trans1() {
    Book book = new Book();
    book.setId(10);
    book.setName("test");
    boolean save = save(book);
    log.info(save + "");

    BookServiceImpl bookService = (BookServiceImpl) AopContext.currentProxy();
    for (int i = 0; i < 3; i++) {
        try {
            // NESTED 的方式,各自错了,回滚各自的内容,并不会影响其他事务
            bookService.otherTrans(i);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }
    // int a = 1 / 0;
    return "ok";
}

@Transactional(propagation = Propagation.NESTED)
public void otherTrans1(int i) {
    Book book = new Book();
    book.setId(20 + i);
    book.setName("otherTrans" + i);
    save(book);
    if (i == 2) {
        int a = 1 / 0;
    }
}


@Override
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public String trans2() {
    Book book = new Book();
    book.setId(10);
    book.setName("test");
    boolean save = save(book);
    log.info(save + "");

    BookServiceImpl bookService = (BookServiceImpl) AopContext.currentProxy();
    try {
        /*
          这里一定要站在 是否是同一个事务中来看待这些传播行为
         */
        // REQUIRED :即使吃掉异常,也会回滚,因为是同一个事务
        // NESTED :吃掉异常,外部方法不会回滚,只会滚 内部 方法,因为有存档点
        // REQUIRES_NEW :吃掉异常,外部方法不会回滚,只会滚 内部 方法,因为是不同事务
        // NEVER :吃掉异常,外部方法不会回滚,内部方法报错不执行而已
        bookService.otherTrans2(23);
    } catch (Exception e) {
        e.printStackTrace();
    }
    // int a = 1 / 0;
    return "ok";
}

@Transactional(propagation = Propagation.NEVER)
public void otherTrans2(int i) {
    Book book = new Book();
    book.setId(20 + i);
    book.setName("otherTrans" + i);
    save(book);
    int a = 1 / 0;

}
本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:alixiixcom@163.com