国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 詳解Spring事務回滾和事務提交

詳解Spring事務回滾和事務提交

2021-08-27 11:42檸檬時間 Java教程

這篇文章主要介紹了詳解Spring事務回滾和事務提交的相關資料,幫助大家更好的理解和學習使用spring框架,感興趣的朋友可以了解下

事務回滾

回滾邏輯如下:

  1. 判斷是否存在事務,只有存在事務才執行回滾
  2. 根據異常類型判斷是否回滾。如果異常類型不符合,仍然會提交事務
  3. 回滾處理

詳細解析

  1. 判斷是否存在事務,只有存在事務才執行回滾,即是否有@Transactional事務注解或相關事務切面
  2. 根據異常類型判斷是否回滾。如果異常類型不符合,仍然會提交事務

根據@Transactional注解中rollbackFor、rollbackForClassName、noRollbackForClassName配置的值,找到最符合ex的異常類型,如果符合的異常類型不是NoRollbackRuleAttribute,則可以執行回滾。
如果@Transactional沒有配置,則默認使用RuntimeException和Error異常。
代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
@Override
public boolean rollbackOn(Throwable ex) {
 if (logger.isTraceEnabled()) {
  logger.trace("Applying rules to determine whether transaction should rollback on " + ex);
 }
 
 RollbackRuleAttribute winner = null;
 int deepest = Integer.MAX_VALUE;
 
 //rollbackRules保存@Transactional注解中rollbackFor、rollbackForClassName、noRollbackForClassName配置的值
 if (this.rollbackRules != null) {
  for (RollbackRuleAttribute rule : this.rollbackRules) {
   int depth = rule.getDepth(ex);
   if (depth >= 0 && depth < deepest) {
    deepest = depth;
    winner = rule;
   }
  }
 }
 
 if (logger.isTraceEnabled()) {
  logger.trace("Winning rollback rule is: " + winner);
 }
 
 // User superclass behavior (rollback on unchecked) if no rule matches.
 //若@Transactional沒有配置,默認調用父類的
 if (winner == null) {
  logger.trace("No relevant rollback rule found: applying default rules");
  return super.rollbackOn(ex);
 }
 
 return !(winner instanceof NoRollbackRuleAttribute);
}
 
//super
@Override
public boolean rollbackOn(Throwable ex) {
 return (ex instanceof RuntimeException || ex instanceof Error);
}

回滾處理

  1. 如果存在安全點,則回滾事務至安全點,這個主要是處理嵌套事務,回滾安全點的操作還是交給了數據庫處理.
  2. 當前事務是一個新事務時,那么直接回滾,使用的是DataSourceTransactionManager事務管理器,所以調用DataSourceTransactionManager#doRollback,直接調用數據庫連接的回滾方法。
  3. 當前存在事務,但又不是一個新的事務,只把事務的狀態標記為read-only,等到事務鏈執行完畢后,統一回滾,調用DataSourceTransactionManager#doSetRollbackOnly
  4. 清空記錄的資源并將掛起的資源恢復

代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
private void processRollback(DefaultTransactionStatus status) {
 try {
  try {
   triggerBeforeCompletion(status);
   //如果有安全點,回滾至安全點
   if (status.hasSavepoint()) {
    if (status.isDebug()) {
     logger.debug("Rolling back transaction to savepoint");
    }
    status.rollbackToHeldSavepoint();
   }
   //如果是新事務,回滾事務
   else if (status.isNewTransaction()) {
    if (status.isDebug()) {
     logger.debug("Initiating transaction rollback");
    }
    doRollback(status);
   }
   //如果有事務但不是新事務,則把標記事務狀態,等事務鏈執行完畢后統一回滾
   else if (status.hasTransaction()) {
    if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {
     if (status.isDebug()) {
      logger.debug("Participating transaction failed - marking existing transaction as rollback-only");
     }
     doSetRollbackOnly(status);
    }
    else {
     if (status.isDebug()) {
      logger.debug("Participating transaction failed - letting transaction originator decide on rollback");
     }
    }
   }
   else {
    logger.debug("Should roll back transaction but cannot - no transaction available");
   }
  }
  catch (RuntimeException ex) {
   triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
   throw ex;
  }
  catch (Error err) {
   triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
   throw err;
  }
  triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
 }
 finally {
  //清空記錄的資源并將掛起的資源恢復
  cleanupAfterCompletion(status);
 }
}

事務提交

事務提交邏輯如下:

  1. 判斷事務是否已經完成,如果完成拋出異常
  2. 判斷事務是否已經被標記成回滾,則執行回滾操作
  3. 嵌入事務標記回滾,如果嵌入事務拋出了異常執行了回滾,但是在調用方把嵌入事務的異常個捕獲沒有拋出,就會執行這一步。
  4. 提交事務

代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
@Override
public final void commit(TransactionStatus status) throws TransactionException {
 //1. 判斷事務是不是已經完成
 if (status.isCompleted()) {
  throw new IllegalTransactionStateException(
    "Transaction is already completed - do not call commit or rollback more than once per transaction");
 }
 
 DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
 //2. 如果在事務鏈中已經被標記回滾,那么不會嘗試提交事務,直接回滾,不過我沒找到在哪設置這個值
 if (defStatus.isLocalRollbackOnly()) {
  if (defStatus.isDebug()) {
   logger.debug("Transactional code has requested rollback");
  }
  processRollback(defStatus);
  return;
 }
 //3. shouldCommitOnGlobalRollbackOnly()默認返回false,isGlobalRollbackOnly是在嵌入事務回滾的時候賦值的
 if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
  if (defStatus.isDebug()) {
   logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
  }
  processRollback(defStatus);
  // Throw UnexpectedRollbackException only at outermost transaction boundary
  // or if explicitly asked to.
  if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) {
   throw new UnexpectedRollbackException(
     "Transaction rolled back because it has been marked as rollback-only");
  }
  return;
 }
 //4. 提交事務
 processCommit(defStatus);
}

以上就是詳解Spring事務回滾和事務提交的詳細內容,更多關于Spring事務回滾和事務提交的資料請關注服務器之家其它相關文章!

原文鏈接:https://segmentfault.com/a/1190000039355614

延伸 · 閱讀

精彩推薦
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網2942020-09-17
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩中求8032021-07-12
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經有好久沒有升過級了。升級完畢重啟之后,突然發現好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發現了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7472021-02-04
  • Java教程Java BufferWriter寫文件寫不進去或缺失數據的解決

    Java BufferWriter寫文件寫不進去或缺失數據的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數據的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程Java實現搶紅包功能

    Java實現搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
主站蜘蛛池模板: 偷拍一区二区 | 人人超碰免费 | 精品久久国产老人久久综合 | 欧美激情一区二区三级高清视频 | 国产一区二区三区免费播放 | 一区二区av | 精品少妇一区二区三区在线播放 | 久久久久999 | 私人毛片免费高清视频 | 精品视频二区 | 国产一区二区三区视频在线观看 | 国产精品久久久久无码av | 国产精品区一区二区三区 | 免费在线看污网站 | 欧美日韩一区二区视频在线观看 | 成人网av| 91成人黄色| 精品久久久久一区二区国产 | 精品免费久久久久久久苍 | 91操操| 91在线看黄 | 亚洲高清精品视频 | 中文字幕在线观看日本 | 国产三级 | 伊人黄| 色图综合 | 久久亚洲欧美日韩精品专区 | 国产精品三级久久久久久电影 | 黄色小视频在线 | 国产成人精品免费视频大全最热 | 午夜av电影 | 国产一级毛片国语一级 | 视频1区2区 | 无码日韩精品一区二区免费 | 黄色99 | 一区二区三区久久久 | 亚洲国产第一页 | 精品久久久久久久人人人人传媒 | 国产日韩精品一区 | 日本欧美在线观看 | 国产精品免费久久久久久久久久中文 |