欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring中七種事務傳播機制詳解

 更新時間:2024年01月17日 10:21:50   作者:java-zh  
這篇文章主要介紹了Spring中七種事務傳播機制詳解,Spring在TransactionDefinition接口中規(guī)定了7種類型的事務傳播行為,Propagation枚舉則引用了這些類型,開發(fā)過程中我們一般直接用Propagation枚舉,需要的朋友可以參考下

一、概述

Spring在TransactionDefinition接口中規(guī)定了7種類型的事務傳播行為。

Propagation枚舉則引用了這些類型,開發(fā)過程中我們一般直接用Propagation枚舉。

1.1 Propagation源碼

public enum Propagation {    REQUIRED(0),    SUPPORTS(1),    MANDATORY(2),    REQUIRES_NEW(3),    NOT_SUPPORTED(4),    NEVER(5),    NESTED(6);    private final int value;    private Propagation(int value) {        this.value = value;    }    public int value() {        return this.value;    }}public enum Propagation {
    REQUIRED(0),
    SUPPORTS(1),
    MANDATORY(2),
    REQUIRES_NEW(3),
    NOT_SUPPORTED(4),
    NEVER(5),
    NESTED(6);
    private final int value;
    private Propagation(int value) {
        this.value = value;
    }
    public int value() {
        return this.value;
    }
}

1.2、類型解析

  • Propagation.REQUIRED(默認機制):如果當前存在事務,那么就加入這個事務,不存在就新建一個事務。
  • Propagation.SUPPORTS:如果當前有事務,加入事務,如果沒有則不使用事務
  • Propagation.MANDATORY:使用當前事務,如果當前沒有事務,就拋出異常
  • Propagation.REQUIRES_NEW:新建新的事務,如果當前存在事務,就把當前事務掛起
  • Propagation.NOT_SUPPORTED:以非事務方式執(zhí)行操作,如果當前存在事務,把當前事務掛起
  • Propagation.NEVER:以非事務方式執(zhí)行操作,如果當前存在事務,就拋出異常
  • Propagation.NESTED:如果當前存在事務,則嵌套在事務內(nèi)執(zhí)行。如果當前沒有事務,則執(zhí)行Propagation.REQUIRED類似操作

1.3 分類舉例

傳播機制解釋
Propagation.NEVER非事務執(zhí)行操作,存在事務,拋出異常
Propagation.MANDATORY使用當前事務,沒有事務,拋出異常

代碼案例:

//controller
@RestController
@RequestMapping("/op")
public class TestController {
    @Autowired
    private TestService testService;
    @GetMapping("/test1")
    public void test1() {
        testService.test1();
    }
}
//service
public interface TestService2 extends BaseService<Test> {
    void test2();
    void test3();
}
@Service
public class TestServiceImpl2 extends BaseServiceImpl<TestMapper, Test> implements TestService2 {
    @Override
    @Transactional(propagation = Propagation.NEVER, rollbackFor = Exception.class)
    public void test2() {
        System.out.println("test2 存在事務 NEVER");
    }
    @Override
    public void test3() {
        System.out.println("test3 沒有事務");
    }
}
public interface TestService extends BaseService<Test> {
    int insert(Test test);
    int update(Test test);
    void test1();
    void test4();
}
@Service
public class TestServiceImpl extends BaseServiceImpl<TestMapper, Test> implements TestService {
    @Autowired
    private TestService2 testService2;
    @Override
    public int insert(Test test) {
        return getBaseMapper().insert(test);
    }
    @Override
    public int update(Test test) {
        return getBaseMapper().updateById(test);
    }
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void test1() {
        System.out.println("test1 存在事務 REQUIRED");
        //如果在調(diào)用NEVER類型的時候,一定要用這種代理的方式,NEVER才會生效
        testService2.test2();
    }
    @Override
    @Transactional(propagation = Propagation.MANDATORY, rollbackFor = Exception.class)
    public void test4() {
        System.out.println("test4 存在事務 MANDATORY");
        testService2.test3();
    }
}

測試結(jié)果

Propagation.NEVER

Propagation.MANDATORY

傳播機制解釋
Propagation.REQUIRED需要在事務中執(zhí)行,外層有事務就加入,沒有事務就自己創(chuàng)建一個事務
Propagation.REQUIRES_NEW需要在一個新的事務中執(zhí)行,這個事務獨立于外層的事務,互不影響

Propagation.REQUIRES_NEW案例

@Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void test5() {
        System.out.println("當前事務 REQUIRED ");
        Test test = new Test();
        test.setUserName("上海");
        test.setAddress("中國");
        getBaseMapper().insert(test);
        //test6用REQUIRES_NEW修飾,里面有異常,那么當前的事務也會回滾,如果test5有異常,test6不會受到影響
        testService2.test6();
        //當前事務進行回滾,test6內(nèi)容會正常增加
        int i = 1/0;
    }
@Override
    @Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor = Exception.class)
    public void test6() {
        System.out.println("創(chuàng)建了一個新的事務");
        Test test = new Test();
        test.setUserName("廣州");
        test.setAddress("中國");
        getBaseMapper().insert(test);
    }

注意點:

REQUIRES_NEW如果在內(nèi)層,它里面的事務獨立于外層的事務,外層事務如果發(fā)送異常回滾跟REQUIRES_NEW里面內(nèi)容無關,如果REQUIRES_NEW里面內(nèi)容回滾,那么外層的事務也會跟著回滾。

Propagation.REQUIRES_NEW測試結(jié)果

傳播機制解釋
Propagation.SUPPORTS外層有事務就加入,如果沒有事務,就以非事務方式執(zhí)行
Propagation.NOT_SUPPORTED以非事務的方式執(zhí)行,執(zhí)行的時候,先將外層的事務掛起,允許外層有事務。
傳播機制解釋
Propagation.NESTED        嵌套事務,它是已經(jīng)存在事務的真正子事務,嵌套事務開始執(zhí)行時,會取得一個保存點(savepoint),如果這個嵌套事務失敗,將會回滾導這個保存點(savepoint),而不是整個事務的回滾
@Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void test7() {
        System.out.println("當前事務 REQUIRED ");
        Test test = new Test();
        test.setUserName("上海");
        test.setAddress("中國");
        getBaseMapper().insert(test);
        //NESTED事務如果進行回滾,但是不會對它外層的事務造成影響
        try{
            testService2.test8();
        }catch (Exception e){
        }
    }
  @Override
    @Transactional(propagation = Propagation.NESTED,rollbackFor = Exception.class)
    public void test8() {
        System.out.println("創(chuàng)建了一個新的子事務");
        Test test = new Test();
        test.setUserName("廣州");
        test.setAddress("中國");
        getBaseMapper().insert(test);
        int i = 1/0;
    }

二、總結(jié)

2.1 REQUIRED,REQUIRES_NEW,NESTED

狀態(tài)REQUIRES_NEW(兩個獨立事務)NESTED(B事務嵌套在A事務中)REQUIRED同一個事務
A異常B正常A回滾,B正常提交A與B一起回滾A與B一起回滾
A正常B異常B先回滾,A正常提交B先回滾,A再正常提交A與B一起回滾
A正常B正常B先提交,A再提交A與B一起提交A與B一起提交

2.2 三者不同

REQUIRED

  • 假設在A?法存在?個當前事務,B?法的事務傳播機制為REQUIRED,則B?法會合并到A?法的事務?執(zhí)?。
  • A、B任意?個?法異常(默認是RuntimeException和Error)都會導致A、B的操作被回滾。
  • Spring事務管理器不會吞異常。
  • B異常后會拋給A,A如果沒有catch這個異常,會繼續(xù)向上拋。如果A catch住了,Spring事務管理器會替A向上拋?個
  • UnexpectedRollbackException??傊?,?旦A、B回滾,A的調(diào)???定能收到?個異常感知到回滾。(問題所在)

REQUIRES_NEW

  • 如果B發(fā)?異常,B事務?定回滾,B的異常隨后會拋給A,如果A catch住了這個異常,A不會回滾,否則A也會回滾。
  • 如果A發(fā)?異常,則只會回滾A,不會回滾B。

NESTED

  • 如果B異常,B?定回滾,B的異常隨后會拋給A,如果A catch住了這個異常,A不會回滾,否則A也會回滾。這種情況和REQUIRES_NEW?樣。
  • 如果A發(fā)?異常,則A、B都會回滾。

2.3 手動回滾

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void test7() {
        System.out.println("當前事務 REQUIRED ");
        Test test = new Test();
        test.setUserName("上海");
        test.setAddress("中國");
        getBaseMapper().insert(test);
        //NESTED事務如果進行回滾,但是不會對它外層的事務造成影響
        try{
            testService2.test8();
        }catch (Exception e){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }

到此這篇關于Spring中七種事務傳播機制詳解的文章就介紹到這了,更多相關Spring事務傳播機制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論