真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Spring事務(wù)和事務(wù)的傳播機(jī)制-創(chuàng)新互聯(lián)

1.Spring 中事務(wù)的實(shí)現(xiàn)方式

Spring 中的操作主要分為兩類:

在甘泉等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì) 網(wǎng)站設(shè)計(jì)制作定制網(wǎng)站建設(shè),公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),成都品牌網(wǎng)站建設(shè),成都全網(wǎng)營(yíng)銷推廣,外貿(mào)營(yíng)銷網(wǎng)站建設(shè),甘泉網(wǎng)站建設(shè)費(fèi)用合理。
  • 編程式事務(wù) (了解)

  • 聲明式事務(wù)

編程式事務(wù)就是手寫代碼操作事務(wù), 而聲明式事務(wù)是利用注解來自動(dòng)開啟和提交事務(wù). 并且編程式事務(wù)用幾乎不怎么用. 這就好比汽車的手動(dòng)擋和自動(dòng)擋, 如果有足夠的的錢, 大部分人應(yīng)該都會(huì)選擇自動(dòng)擋.
聲明式事務(wù)也是如此, 它不僅好用, 還特別方便.

1.1 Spring 編程式事務(wù) (了解)

編程式事務(wù)和 MySQL 中操作事務(wù)類似, 也是三個(gè)重要步驟:

  1. 開啟事務(wù)

  1. 提交事務(wù)

  1. 回滾事務(wù)

【代碼實(shí)現(xiàn)】

@RequestMapping("/user")
public class UserController1 {
    @Autowired
    private UserService userService;

    @Autowired  // JDBC 事務(wù)管理器
    private DataSourceTransactionManager dataSourceTransactionManager;

    @Autowired  // 定義事務(wù)屬性
    private TransactionDefinition transactionDefinition;

    @RequestMapping("/add")
    public int add(String username, String password) {
        // 非空校驗(yàn)
        if(!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {
            return 0;
        }
        // 事務(wù) [得到并開啟事務(wù)]
        TransactionStatus transactionStatus =
                dataSourceTransactionManager.getTransaction(transactionDefinition);

        int result = userService.add(username, password, null);
        System.out.println("添加影響行數(shù): " + result);

        // 提交事務(wù) or 回滾
        dataSourceTransactionManager.rollback(transactionStatus);
        //  dataSourceTransactionManager.commit(transactionStatus);
        return result;
    }
}
DataSourceTransactionManager 和 TransactionDefinition 是 SpringBoot 內(nèi)置的兩個(gè)對(duì)象.
DataSourceTransactionManager : 用來獲取事務(wù)(開啟事務(wù))、提交或回滾事務(wù).
TransactionDefinition : 它是事務(wù)的屬性,在獲取事務(wù)的時(shí)候需要將這個(gè)對(duì)象傳遞進(jìn)去從而獲得?個(gè)事務(wù) TransactionStatus.

【測(cè)試編式事務(wù)】

上述代碼的主要要業(yè)務(wù)邏輯就是基于 MyBatis實(shí)現(xiàn)了一個(gè)新增方法, 接下來我們測(cè)試一下編程式事務(wù)中的回滾操作是否生效.

  1. 在測(cè)試之前先查看一下數(shù)據(jù)庫(kù)中的用戶信息 (userinfo) :

  1. 啟動(dòng)程序后, 在瀏覽器輸入: 127.0.0.1:8080/user/add?username=李華&password=123

3. 此時(shí)我們看見控制臺(tái)顯示添加數(shù)據(jù)成功, 那么要知道代碼中的回滾是否生效, 需要查看數(shù)據(jù)庫(kù)是否真正的把數(shù)據(jù)添加進(jìn)去了.

4. 發(fā)現(xiàn)數(shù)據(jù)庫(kù)中并沒有添加數(shù)據(jù), 說明回滾操作生效了. 而提交事務(wù) commit 就和普通的添加操作差不多, 下來可以自己試一下.

1.2 Spring 聲明式事務(wù)

聲明式事務(wù)的實(shí)現(xiàn)相較于編程式事務(wù)來說, 就要簡(jiǎn)單太多了, 只需要在需要的方法上添加 @Transactional注解就可以實(shí)現(xiàn)了.

@Transactional 注解的作用:

當(dāng)進(jìn)入方法的時(shí)候, 它就會(huì)自動(dòng)開啟事務(wù), 當(dāng)方法結(jié)束后, 它就會(huì)自動(dòng)提交事務(wù). 說白了它就是 AOP 的一個(gè)環(huán)繞通知. 只要加了 @Transactional 注解的方法, 都有一個(gè)事務(wù)的 AOP , 這都是 Spring 幫我們封裝好的.

@Transactional 注解的執(zhí)行流程:

1. 方法執(zhí)行之前, 先開啟事務(wù), 當(dāng)方法成功執(zhí)行完成之后會(huì)自動(dòng)提交事務(wù).
2. 如果方法在執(zhí)行過程中發(fā)生了異常, 那么事務(wù)會(huì)自動(dòng)回滾.

【代碼實(shí)現(xiàn)】

 ? @RequestMapping("/add2")
    @Transactional // 聲明式事務(wù)
    public int add2(String username, String password) {
        // 非空校驗(yàn)
        if(!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {
            return 0;
        }
        int result = userService.add(username, password, null);
        System.out.println("添加影響行數(shù): " + result);
        return result;
    }

對(duì)于方法執(zhí)行成功的情況就不測(cè)試了, 它和普通的插入數(shù)據(jù)沒有多大區(qū)別, 重點(diǎn)在于理解 @Transactional注解的含義和作用即可.

【異常情況一】

 ? @RequestMapping("/add2")
    @Transactional // 聲明式事務(wù)
    public int add2(String username, String password) {
        // 非空校驗(yàn)
        if(!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {
            return 0;
        }
        int result = userService.add(username, password, null);
        System.out.println("添加影響行數(shù): " + result);
? ? ? ? int num = 10 / 0;
        return result;
    }

當(dāng)我們寫出 int num = 10 / 0; 這樣一條語句的時(shí)候, 看看 @Transactional 是否會(huì)進(jìn)行回滾操作:

啟動(dòng)程序, 瀏覽器訪問 : 127.0.0.1:8080/user/add2?username=王五&password=123

此時(shí)程序已經(jīng)報(bào)錯(cuò)了, 并且打印了添加成功語句, 是否真正添加成功, 還是說進(jìn)行了回滾操作, 就要查詢數(shù)據(jù)庫(kù):

發(fā)現(xiàn)數(shù)據(jù)庫(kù)中并沒有王五這條數(shù)據(jù), 說明在發(fā)生異常的時(shí)候, @Transactional 注解幫我們做了回滾操作.

【異常情況二】

對(duì)于上述代碼拋出異常后, @Transactional 注解幫我們進(jìn)行回滾, 這一點(diǎn)很好理解, 那么如果我們將這個(gè)異常捕獲了, @Transactional 注解是否還會(huì)進(jìn)行回滾操作呢 >>

 ? @RequestMapping("/add2")
    @Transactional // 聲明式事務(wù)
    public int add2(String username, String password) {
        // 非空校驗(yàn)
        if(!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {
            return 0;
        }
        int result = userService.add(username, password, null);
        System.out.println("添加影響行數(shù): " + result);
        try {
            int num = 10 / 0;
        } catch (Exception e) {
            
        }
        return result;
    }

執(zhí)行結(jié)果: 此時(shí)程序沒有發(fā)生報(bào)錯(cuò)了.

為了驗(yàn)證是否進(jìn)行回滾, 繼續(xù)查詢數(shù)據(jù)庫(kù)

此時(shí)我們發(fā)現(xiàn), @Transactional 注解并沒有進(jìn)行回滾操作, 而是提交了事務(wù). 這是為什么 ??

因?yàn)楫?dāng)我們捕捉到異常的時(shí)候, Spring 框架會(huì)認(rèn)為我們有能力處理, 所以就不會(huì)進(jìn)行回滾, 而當(dāng)發(fā)生異常我們不處理的時(shí)候, Spring 框架就會(huì)采取保守的做法, 他知道我們沒有能力去處理這個(gè)異常, 所以就會(huì)幫我們回滾. 所以當(dāng)出現(xiàn)異常的時(shí)候, 我們要根據(jù)這個(gè)異常是否被處理來判斷最終是提交數(shù)據(jù)了, 還是進(jìn)了回滾操作.

1.2.1 聲明式事務(wù)的手動(dòng)回滾

當(dāng)?shù)诙N異常情況, 捕獲異常之后, 事務(wù)并沒有進(jìn)行回滾, 我們是需要做出一些處理的. 既然程序發(fā)生了異常, 我們一般就需要進(jìn)行回滾操作的. 對(duì)于這種捕獲異常的情況,我們有兩種方式進(jìn)行回滾:

  • 將異常繼續(xù)拋出.

  • 通過代碼手動(dòng)回滾事務(wù).

【代碼示例】- 將異常繼續(xù)拋出

 ? @RequestMapping("/add2")
    @Transactional // 聲明式事務(wù)
    public int add2(String username, String password) {
        // 非空校驗(yàn)
        if(!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {
            return 0;
        }
        int result = userService.add(username, password, null);
        System.out.println("添加影響行數(shù): " + result);
        try {
            int num = 10 / 0;
        } catch (Exception e) {
            throw e; // 將異常繼續(xù)拋出
        }
        return result;
    }

測(cè)試代碼是否回滾,還是和前面一樣的操作,就不贅述了. 代碼的最終執(zhí)行結(jié)果肯定是進(jìn)行了回滾操作.

【代碼示例】- 手動(dòng)回滾事務(wù)

 ? @RequestMapping("/add2")
    @Transactional // 聲明式事務(wù)
    public int add2(String username, String password) {
        // 非空校驗(yàn)
        if(!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {
            return 0;
        }
        int result = userService.add(username, password, null);
        System.out.println("添加影響行數(shù): " + result);
        try {
            int num = 10 / 0;
        } catch (Exception e) {
            // throw e;
            System.out.println("程序發(fā)生異常: " + e.getMessage());
            // 手動(dòng)回滾事務(wù) [得到當(dāng)前事務(wù)并設(shè)置回滾] - 通過事務(wù)的切面拿到當(dāng)前事務(wù), 再設(shè)置回滾
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return result;
    }
手動(dòng)回滾事務(wù) : 通過事務(wù)的 AOP 拿到當(dāng)前的事務(wù), 然后設(shè)置回滾.

這種方式來處理事務(wù)的回滾, 顯得更加優(yōu)雅, 更推薦使用.

1.2.2 @Transactional 的工作原理

@Transactional 是基于 AOP實(shí)現(xiàn)的, AOP又是基于動(dòng)態(tài)代理實(shí)現(xiàn)的 (JDK, CGLIB), 它在開始執(zhí)行業(yè)務(wù)之前, 會(huì)通過代理實(shí)現(xiàn)開啟事務(wù), 在執(zhí)行成功之后再提交事務(wù), 如果中途出現(xiàn)了異常, 就會(huì)回滾事務(wù).

@Transactional 實(shí)現(xiàn)思路

切面會(huì)攔截所有加了 @Transactional 注解的方法, 于是切點(diǎn)就有了, 然后開啟事務(wù)與提交事務(wù)/回滾事務(wù)之間相當(dāng)于是一個(gè)環(huán)繞通知.

2.事務(wù)隔離級(jí)別

在學(xué) MySQL 的時(shí)候, 我們就已經(jīng)知道了事務(wù)有四大特性: (ACID)

原子性 (Atomicity),
持久性(Consistency),
一致性 (Isolation) ,
隔離性 (Durability);

具體的概念在這篇博客中已經(jīng)做過說明. - MySQL 事務(wù)的四大特性.

這四種特性中只有隔離性是可以設(shè)置的, 那么為什么要設(shè)置事務(wù)的隔離級(jí)別呢 ??

-- 為了保障多個(gè)并發(fā)事務(wù)執(zhí)行更可控, 更符合操作者的預(yù)期.

2.1 Spring 中設(shè)置事務(wù)的隔離級(jí)別

MySQL 中事務(wù)的隔離級(jí)別分為四種:

事務(wù)隔離級(jí)別

臟讀

不可重復(fù)讀

幻讀

讀未提交 (READ UNCOMMITTED)

讀已提交 (READ COMMITTED)

×

可重復(fù)讀 (REPEATABLE READ)

×

×

串行化 (SERIALIZABLE)

×

×

×

MySQL 默認(rèn)事務(wù)的隔離級(jí)別 : 可重復(fù)讀, 可通過命令 select @@global.tx_isolation,@@tx_isolation; 來進(jìn)行查看.

1. 臟讀 : 一個(gè)事務(wù)A,在執(zhí)行的過程中,對(duì)數(shù)據(jù)進(jìn)行了一系列修改,在提交到數(shù)據(jù)庫(kù)之前(完成事務(wù)之前),另一個(gè)事務(wù)B,讀取了對(duì)應(yīng)的數(shù)據(jù),此時(shí)這個(gè)B讀到的數(shù)據(jù)都是一些臨時(shí)的結(jié)果,后續(xù)可能馬上就被A給改了,此時(shí)B的讀取行為就是"臟讀"!

2. 不可重復(fù)讀 : 事務(wù)A提交了事務(wù)之后,事務(wù)B才開始讀(讀的時(shí)候加了鎖),然后B在執(zhí)行的過程中,A再次開啟了事務(wù), 修改了 B 讀取的數(shù)據(jù),此時(shí)B執(zhí)行中,就導(dǎo)致兩次讀取操作結(jié)果可能就不一致!(側(cè)重于修改)

3. 幻讀 : 事務(wù)B讀取過程中,事務(wù)A進(jìn)行了更新操作 ( 新增/刪除/修改),沒有直接影響B(tài)正在讀取的數(shù)據(jù),但是影響到了B讀取的結(jié)果集,事務(wù)B兩次讀取到的結(jié)果集不一樣,這個(gè)就是幻讀!幻讀相當(dāng)于不可重復(fù)讀的特殊情況。(側(cè)重于新增和刪除)

2.1.1 Spring 中事務(wù)的隔離級(jí)別

Spring 中事務(wù)的隔離級(jí)別有五個(gè), MySQL 中的四個(gè)加上 DEFAULT 級(jí)別;

Isolation.DEFAULT : 以連接的數(shù)據(jù)庫(kù)的事務(wù)隔離級(jí)別為主.(以數(shù)據(jù)庫(kù)的全局事務(wù)隔離級(jí)別為主)

在 Spring 中如何設(shè)置事務(wù)的隔離級(jí)別>>>

@RequestMapping("/add")
@Transactional(isolation = Isolation.DEFAULT)
public int add(String username, String password) {
    // 業(yè)務(wù)邏輯
}

3. Spring 事務(wù)的傳播機(jī)制

什么是事務(wù)的傳播機(jī)制 ??

在回答這個(gè)問題前, 先給大家舉個(gè)例子 >>

1. 拋開事務(wù)的傳播機(jī)制不說, 我們的業(yè)務(wù)就像 UU 跑腿一樣, 你在你家附近買了一樣?xùn)|西, 然后讓 UU跑腿的人送到你的手里, 如果送到了就沒事 (commit), 如果沒送到, 就可以找到對(duì)應(yīng)跑腿的人 (或店家) 進(jìn)行相應(yīng)的賠償 (rollback).
2. 可是實(shí)際生活中, 在網(wǎng)上買東西的人相對(duì)來說要多一些, 如果你在深圳, 但是在北京的一家網(wǎng)店上買了東西, 這時(shí)候就不可能叫 UU跑腿來送到你手里了. 那么快遞一般都要經(jīng)過很多個(gè)運(yùn)輸點(diǎn), 這多個(gè)運(yùn)輸點(diǎn)對(duì)應(yīng)著多批人, 如果你的快遞在中途被弄丟了, 他們應(yīng)該要怎樣賠償, 由誰來賠償, 這就需要牽扯到了多個(gè)事務(wù)之間的傳播機(jī)制了.

事務(wù)的隔離級(jí)別 : 解決的是多個(gè)事務(wù)同時(shí)調(diào)用數(shù)據(jù)庫(kù)的問題!

而事務(wù)的傳播機(jī)制解決的是一個(gè)事務(wù)在多個(gè)節(jié)點(diǎn) (方法) 中傳遞問題!

上述例子將的就是上圖中多個(gè)方法調(diào)用的時(shí)候, 發(fā)生異常應(yīng)該要怎么去處理, 這就是傳播機(jī)制的意義所在!

3.1 事務(wù)傳播機(jī)制的級(jí)別

事務(wù)傳播機(jī)制的級(jí)別分為 7 種:

1. Propagation.REQUIRED : 默認(rèn)的事務(wù)傳播級(jí)別, 它表示如果當(dāng)前存在事務(wù),則加入該事務(wù); 如果當(dāng)前沒有事務(wù), 則創(chuàng)建?個(gè)新的事務(wù).
2. Propagation.SUPPORTS : 如果當(dāng)前存在事務(wù), 則加入該事務(wù);如果當(dāng)前沒有事務(wù),則以非事務(wù)的
方式繼續(xù)運(yùn)行.
3. Propagation.MANDATORY : (mandatory:強(qiáng)制性) 如果當(dāng)前存在事務(wù),則加入該事務(wù); 如果當(dāng)
前沒有事務(wù),則拋出異常.
4. Propagation.REQUIRES_NEW:表示創(chuàng)建一個(gè)新的事務(wù), 如果當(dāng)前存在事務(wù), 則把當(dāng)前事務(wù)掛
起. 也就是說不管外部方法是否開啟事務(wù), Propagation.REQUIRES_NEW 修飾的內(nèi)部方法會(huì)新開
啟自己的事務(wù), 且開啟的事務(wù)相互獨(dú)立, 互不干擾.
5. Propagation.NOT_SUPPORTED:以非事務(wù)方式運(yùn)行,如果當(dāng)前存在事務(wù),則把當(dāng)前事務(wù)掛起.
6. Propagation.NEVER:以非事務(wù)方式運(yùn)行,如果當(dāng)前存在事務(wù),則拋出異常.
7. Propagation.NESTED:如果當(dāng)前存在事務(wù),則 創(chuàng)建?個(gè)事務(wù)作為當(dāng)前事務(wù)的嵌套事務(wù)來運(yùn)行;如
果當(dāng)前沒有事務(wù),則該取值等價(jià)于 Propagation.REQUIRED

這 7 中事務(wù)傳播級(jí)別又可以分為三大類:

如果對(duì)于這三類事務(wù)傳播機(jī)制, 不太理解的話, 下面把事務(wù)比做房子, 舉一個(gè)生活中的例子 :

😁😁😁😁😁😁😁😁😁

  1. 支持當(dāng)前事務(wù) (普通伴侶)

  • REQUIRED (需要有) : 有房子就一起住, 沒房子就一起賺錢買房子. (愿意陪你吃苦, 但一定要有房子)

  • SUPPORTS (可以有) : 有房子就一起住, 沒房子就租房子住. (隨緣的, 沒房子也無所謂)

  • MANDATORY (強(qiáng)制有) : 有房子一起住, 沒房子就分手. (不愿陪你吃苦)

  1. 不支持當(dāng)前事務(wù) (強(qiáng)勢(shì)型伴侶)

  • REQUIRES_NEW : 不要你的房子, 咱們必須一起賺錢買房子. (看不上你的房子, 必須買新房子)

  • NOT_SUPPORTED : 不要你的房子, 咱們必須一起租房子. (不住你的房子, 必須租房子)

  • NEVER : 必須一起租房子, 你要有房子就分手. (看不上你的房子, 還得陪你環(huán)房貸)

  1. 嵌套事務(wù) (懂事型伴侶)

  • NESTED : 有房子就以房子為根據(jù)地做點(diǎn)小生意, 賺錢了就繼續(xù)發(fā)展, 賠錢至少還有房子; 如果沒房子就一起賺錢買房子. (無風(fēng)險(xiǎn)創(chuàng)業(yè), 保本懂事型伴侶)

對(duì)于上述3 類事務(wù)傳播機(jī)制, 主要就是 REQUIRED (默認(rèn)級(jí)別) 和 NESTED (嵌套事務(wù)) 不好區(qū)分>>

1. REQUIRED (默認(rèn)級(jí)別) : 一榮俱榮, 一損俱損. 如果當(dāng)前有事務(wù), 執(zhí)行過程中, 如果拋出異常, 那么就一起回滾, 如果否則一起提交.
2. NESTED (嵌套事務(wù)) : 如果當(dāng)前有事務(wù), 創(chuàng)建一個(gè)事務(wù)作為當(dāng)前的嵌套事務(wù)來執(zhí)行, 相當(dāng)于在當(dāng)前事務(wù)這里有一個(gè)保存點(diǎn), 如果執(zhí)行過程中嵌套事務(wù)拋出異常, 就回滾到保存點(diǎn), 只回滾嵌套事務(wù)(局部回滾), 不會(huì)影響上一個(gè)方法中執(zhí)行的結(jié)果.

【代碼實(shí)現(xiàn)】 針對(duì)默認(rèn)級(jí)別和嵌套事務(wù)的一個(gè)代碼實(shí)現(xiàn) >>

下面的代碼針對(duì) add 方法和 save 方法做了一個(gè)事務(wù)默認(rèn)傳播級(jí)別的測(cè)驗(yàn), 兩個(gè)方法都是添加方法, 如果途中沒有拋異常, 數(shù)據(jù)庫(kù)庫(kù)就會(huì)新增兩條數(shù)據(jù), 否則一條也不新增.

Controller :

 ? @RequestMapping("/add2")
    @Transactional(propagation = Propagation.REQUIRED)
    public int add2(String username, String password) {
        // 非空校驗(yàn)
        if(!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {
            return 0;
        }
        int result = userService.add(username, password, null);
        System.out.println("添加影響行數(shù): " + result);

        int result2 = userService.save(username, password, null);
        System.out.println("添加影響行數(shù): " + result2);
        
        return result;
    }

Service :

save 方法中有一個(gè)除 0 異常 >>

 ? @Transactional(propagation = Propagation.REQUIRED)
    public int add(String username, String password, String photo) {
        return userMapper.add(username, password, photo);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public int save(String username, String password, String photo) {
        try {
            int result = 10 / 0;
        } catch (Exception e) {
            System.out.println("ex: " + e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return userMapper.add(username, password, photo);
    }

數(shù)據(jù)庫(kù)當(dāng)前信息 :

瀏覽器訪問 add2 方法, 并傳入?yún)?shù), username=老六&password=123:

可以看到控制臺(tái)打印了兩次添加影響行數(shù) : 1, 且出現(xiàn)一個(gè)除 0 異常, 那么是否真正插入到數(shù)據(jù)庫(kù)中了, 需要查看一下數(shù)據(jù)庫(kù)>>

發(fā)現(xiàn)并沒有, 和上次查詢的結(jié)果還是一樣的. 所以符合我們的預(yù)期. (查看細(xì)致過程可以打斷點(diǎn)進(jìn)行調(diào)試)

【測(cè)試NESTED】

還是上述兩個(gè)方法, 只不過把 Service 種的 save 方法的事務(wù)傳播級(jí)別改為 NESTED.

瀏覽器訪問 add2 方法, 并傳入?yún)?shù) usename=老六&passowrd=123

此時(shí)控制臺(tái)依然打印了兩次添加影響行數(shù) : 1, 查詢數(shù)據(jù)庫(kù)驗(yàn)證插入情況 :

發(fā)現(xiàn) add 方法的新增成功了, 而 save 方法的的新增回滾了, 也就是回滾到保存點(diǎn), 這也符合我們的預(yù)期. (細(xì)致過程可以通過打斷點(diǎn)的方式進(jìn)行調(diào)試查看).


本篇文章就到這里了, 謝謝觀看!!

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧


名稱欄目:Spring事務(wù)和事務(wù)的傳播機(jī)制-創(chuàng)新互聯(lián)
本文鏈接:http://weahome.cn/article/jodsj.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部