亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Spring詳細講解7種事務(wù)傳播方式

 更新時間:2023年01月03日 11:48:40   作者:沖沖沖!!!  
Spring事務(wù)傳播機制是指,包含多個事務(wù)的方法在相互調(diào)用時,事務(wù)是如何在這些方法間傳播的。本文通過示例詳細介紹了Spring的事務(wù)傳播機制,需要的可以參考一下

Spring事務(wù)傳播行為體現(xiàn)在某個service方法調(diào)用另一個service方法,事務(wù)該如何進行下去。

Spring支持7中事務(wù)傳播方式,在Propagation類中可以看到,如下:

REQUIRED(0),
SUPPORTS(1),
MANDATORY(2),
REQUIRES_NEW(3),
NOT_SUPPORTED(4),
NEVER(5),
NESTED(6);

使用方式就是在service方法上加入Transational注解,例如:

@Transactional(propagation = Propagation.NOT_SUPPORTED)

下面逐個介紹下這7中事務(wù)傳播方式:

1. REQUIRED:

Spring的默認事務(wù)傳播方式。從字面意思看,它表示此枚舉修飾的service方法必須運行在一個事務(wù)中,如果當(dāng)前存在一個事務(wù)(比如其他有事務(wù)的service方法調(diào)用此方法),則運行在當(dāng)前事務(wù)中,否則開啟一個新的事務(wù)。

示例代碼如下:

注意:這里methodA調(diào)用methodB必須要用Spring的代理方式,即用testService.methodB()方式調(diào)用,如果只是method()方式調(diào)用則相當(dāng)于this.methodB()在本對象中調(diào)用,事務(wù)不起作用的,一定要是Spring的AOP代理。@Lazy注解是為了防止啟動的時候出現(xiàn)循環(huán)依賴報錯,采用懶加載方式注入Bean。

下面示例中,methodA調(diào)用methodB的時候,會先開啟一個事務(wù),methodB中會使用methodA這個事務(wù),和methodA一起提交或回滾。

@Service
public class TestServiceImpl implements TestService {
    @Resource @Lazy
    private TestService testService;
    @Transactional
    @Override
    public void methodA() {
        testService.methodB();
        System.out.println("CRUD operation in methodA...");
    }
    @Transactional
    @Override
    public void methodB() {
        System.out.println("CRUD operation in methodB...");
    }
}

2. SUPPORTS:

從字面意思看,它是支持的意思,也就是有事務(wù)我也支持,沒有也行。

即:調(diào)用此方法時如果有一個事務(wù),那么就在當(dāng)前事務(wù)中執(zhí)行,和當(dāng)前事務(wù)一起提交或回滾。如果當(dāng)前沒有事務(wù),那么就不開啟事務(wù),在無事務(wù)環(huán)境中執(zhí)行。

下面示例代碼中,methodB是SUPPORTS事務(wù)傳播方式,methodB有沒有事務(wù)取決于調(diào)用它的methodA??梢钥吹酱藭rmethodA是有一個事務(wù)的,所以methodB會在methodA這個事務(wù)中一起提交或回滾。

@Service
public class TestServiceImpl implements TestService {
    @Resource @Lazy
    private TestService testService;
    @Transactional
    @Override
    public void methodA() {
        testService.methodB();
        System.out.println("CRUD operation in methodA...");
    }
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public void methodB() {
        System.out.println("CRUD operation in methodB...");
    }
}

3. MANDATORY:

字面意思:強制。

沒錯,就是一定要在事務(wù)中執(zhí)行,否則就會拋異常。

如下面的代碼,如果直接調(diào)用methodB,由于當(dāng)前沒有事務(wù),會拋出一個IllegalTransactionStateException異常。如果是在methodA中調(diào)用methodB,由于methodA開啟了一個事務(wù),所以methodB會在methodA的事務(wù)中執(zhí)行,不會報錯。

@Service
public class TestServiceImpl implements TestService {
    @Resource @Lazy
    private TestService testService;
    @Transactional
    @Override
    public void methodA() {
        testService.methodB();
        System.out.println("CRUD operation in methodA...");
    }
    @Transactional(propagation = Propagation.MANDATORY)
    @Override
    public void methodB() {
        System.out.println("CRUD operation in methodB...");
    }
}

4. REQUIRES_NEW:

字面意思:開啟一個新的事務(wù)。

這個事務(wù)傳播方式會掛起當(dāng)前事務(wù),開啟一個新的事務(wù),方法會在新的事務(wù)中執(zhí)行并提交,提交完之后,掛起的事務(wù)繼續(xù)往下走。

如下代碼,methodA調(diào)用methodB的時候,當(dāng)前事務(wù)會被掛起,然后在methodB中會開啟一個新的事務(wù),methodB執(zhí)行完并且事務(wù)提交后,methodA的事務(wù)繼續(xù)執(zhí)行。methodB回滾不影響methodA,methodA回滾也不影響methodB。

    @Transactional
    @Override
    public void methodA() {
        testService.methodB();
        System.out.println("CRUD operation in methodA...");
    }
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @Override
    public void methodB() {
        System.out.println("CRUD operation in methodB...");
    }

5. NOT_SUPPORTED:

字面意思:不支持事務(wù)。

用該枚舉修飾的方法一定會運行在非事務(wù)環(huán)境中,即使調(diào)用此方法時有一個事務(wù),也會將該事務(wù)掛起。我們通常將這種方式應(yīng)用于強制要求非事務(wù)的方法中,例如我們現(xiàn)在要將批量數(shù)據(jù)去集成第三方接口然后更新狀態(tài)到DB,不能說某一個數(shù)據(jù)出錯就導(dǎo)致所有數(shù)據(jù)狀態(tài)都回滾,那樣的話,已經(jīng)成功集成過第三方接口的數(shù)據(jù)就又得重新去集成了,會造成重復(fù)調(diào)用,導(dǎo)致第三方系統(tǒng)中的數(shù)據(jù)混亂。

如下代碼,methodA有一個事務(wù),當(dāng)它調(diào)用methodB時,事務(wù)會被掛起,然后methodB中的CRUD操作不會在事務(wù)中執(zhí)行,會立即提交到數(shù)據(jù)庫。methodB執(zhí)行完之后,methodA的事務(wù)繼續(xù)進行,methodA的回滾不影響methodB。

    @Transactional
    @Override
    public void methodA() {
        testService.methodB();
        System.out.println("CRUD operation in methodA...");
    }
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    @Override
    public void methodB() {
        System.out.println("CRUD operation in methodB...");
    }

6. NEVER:

字面意思:永遠也不在事務(wù)中運行。

該枚舉修飾的方法一旦在事務(wù)環(huán)境中就會拋異常。

7. NESTED:

字面意思:嵌套事務(wù)。

這種傳播方式稍微有點復(fù)雜,目前各種廠商對它的支持可能存在差異,需要看具體的事務(wù)管理實現(xiàn)方式。

用此枚舉修飾的方法,當(dāng)外部有事務(wù)的時候,會在里面嵌套一個事務(wù),里面的事務(wù)回滾不會影響外部事務(wù),但外部事務(wù)出錯回滾會將里面的也一起回滾。

如下methodB會在methodA的事務(wù)里面再嵌套一個事務(wù),當(dāng)methodA事務(wù)提交,methodB也會跟著一起提交,當(dāng)methodA出錯回滾,會把methodB也一起回滾。當(dāng)methodB出錯回滾,不會影響methodA的事務(wù),事務(wù)會回退到調(diào)用methodB前的節(jié)點,然后繼續(xù)處理后續(xù)的步驟。

    @Transactional
    @Override
    public void methodA() {
        System.out.println("CRUD operation in methodA before...");
        //保存當(dāng)前狀態(tài),開啟嵌套事務(wù)
        try {
            testService.methodB();
        } catch (Exception e) {
            e.printStackTrace();
        }
        //methodB回滾后不影響methodA事務(wù)繼續(xù)進行
        System.out.println("CRUD operation in methodA...");
    }
    @Transactional(propagation = Propagation.NESTED)
    @Override
    public void methodB() {
        System.out.println("CRUD operation in methodB...");
        throw new RuntimeException("methodB rollback");
    }

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

相關(guān)文章

最新評論