中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Spring中如何實現事務傳播

發布時間:2021-06-17 13:57:42 來源:億速云 閱讀:201 作者:Leah 欄目:編程語言

這期內容當中小編將會給大家帶來有關Spring中如何實現事務傳播,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

事務小貼士

什么是事務呢?簡單來講事務就是邏輯上的一組操作,這些操作要么都執行,要么都不執行。

什么是事務管理呢?所謂事務管理,其實就是“按照給定的事務規則來執行事務的提交或者回滾操作”。

事務的機制實現很大一部依賴事務日志文件(undo log和redo log)。事務日志是一個與數據庫文件分開的文件。它存儲對數據庫進行的所有更改,并全部記錄插入、更新、刪除、提交、回退和數據庫模式變化。事務日志是備份和恢復的重要組件。

訂單出庫失敗

在訂單的包裹出庫之前,會將出庫指令下發到商城,其中包含包裹寄送的快遞信息,以便銷售平臺展示快遞跟蹤信息;同時,為了防止前端因為超賣或者重復下單等原因,已經將訂單取消,會根據前端商城的返回狀態判斷訂單是否可以出庫。

其中,系統交互流程如下,在前端銷售平臺與WMS(倉儲管理系統)之間,會有統一的OMS(訂單管理系統)進行銷售單的管理和數據中轉。

Spring中如何實現事務傳播

當前端銷售平臺收到出庫信息以后,會進行如下的校驗與操作:

Spring中如何實現事務傳播

為了防止調用通知服務的時候出現異常,影響包裹出庫,調用通知服務的代碼是用try-catch語句包裹起來的。

但是,某些訂單在出庫的時候,還是出現了如下異常,出庫失敗:

org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only

	at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:873)
	at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:710)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:534)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:305)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)

根據事務的傳播行為, Transaction rolled back because it has been marked as rollback-only 應該是因為被調用的事務回滾了,當調用一方提交事務的時候因為被標記為了 rollback-only ,因此無法正常提交。

Spring中如何實現事務傳播

Spring事務的傳播機制

下面我們詳細聊一下Spring事務的傳播機制。

Spring的 @Transactional 注解可以用于聲明方法支持事務,Spring底層通過AOP的方式實現事務的控制。

@Transactional 注解中的 Propagation 屬性可以用于指定事務的傳播行為。

/**
 * The transaction propagation type.
 * <p>Defaults to {@link Propagation#REQUIRED}.
 * @see org.springframework.transaction.interceptor.TransactionAttribute#getPropagationBehavior()
 */
Propagation propagation() default Propagation.REQUIRED;

在TransactionDefinition定義中包括了如下幾個表示傳播行為的常量:

  • TransactionDefinition.PROPAGATION_REQUIRES_NEW: 創建一個新的事務,如果當前存在事務,則把當前事務掛起。不支持當前事務。

  • TransactionDefinition.PROPAGATION_NOT_SUPPORTED: 以非事務方式運行,如果當前存在事務,則把當前事務掛起。不支持當前事務。

  • TransactionDefinition.PROPAGATION_NEVER:

以非事務方式運行,如果當前存在事務,則拋出異常。不支持當前事務。

  • TransactionDefinition.PROPAGATION_REQUIRED: 如果當前存在事務,則加入該事務;如果當前沒有事務,則創建一個新的事務。支持當前事務。

  • TransactionDefinition.PROPAGATION_SUPPORTS: 如果當前存在事務,則加入該事務;如果當前沒有事務,則以非事務的方式繼續運行。支持當前事務。

  • TransactionDefinition.PROPAGATION_MANDATORY: 如果當前存在事務,則加入該事務;如果當前沒有事務,則拋出異常。支持當前事務。

  • TransactionDefinition.PROPAGATION_NESTED: 如果當前存在事務,則創建一個事務作為當前事務的嵌套事務來運行;如果當前沒有事務,則該取值等價于TransactionDefinition.PROPAGATION_REQUIRED。支持當前事務。

這里需要指出的是,前面的六種事務傳播行為是 Spring 從 EJB 中引入的,他們共享相同的概念。而 PROPAGATION_NESTED 是 Spring 所特有的。以 PROPAGATION_NESTED 啟動的事務內嵌于外部事務中(如果存在外部事務的話),此時,內嵌事務并不是一個獨立的事務,它依賴于外部事務的存在,只有通過外部的事務提交,才能引起內部事務的提交,嵌套的子事務不能單獨提交。如果熟悉 JDBC 中的保存點(SavePoint)的概念,那嵌套事務就很容易理解了,其實嵌套的子事務就是保存點的一個應用,一個事務中可以包括多個保存點,每一個嵌套子事務。另外,外部事務的回滾也會導致嵌套子事務的回滾。

Spring中如何實現事務傳播

利用事務傳播行為的解決方案

基于上面事務傳播行為的講解,可以將事務的傳播行為設置為 PROPAGATION_REQUIRES_NEW ,這樣當前事務與被調用事務將是兩個不同的事務,可以分別提交或者回滾。

Spring中如何實現事務傳播

在外層事務捕獲異常以后執行如下代碼,會輸出 false ,說明內層事務回滾并未傳播給外層事務: TransactionAspectSupport.currentTransactionStatus().isRollbackOnly()

而在內層事務執行如下代碼,會返回 true ,說明內層事務是一個新的事務,在執行改事務的時候,當前事務會被掛起: TransactionAspectSupport.currentTransactionStatus().isNewTransaction()

這樣就解決了try-catch塊拋出異常因事務傳播行為導致的當前事務無法提交的問題。

利用多線程的解決方案

我們知道,在不同的線程之間,事務是獨立的。對于發送通知消息這樣的業務,適合通過拋出事件的方式,然后通過異步監聽器進行處理。

其流程如下:

Spring中如何實現事務傳播

至于事件模型的實現方式,無論是分布式的Zookeeper、Redis和MQ,還是非分布式的Guava Event Bus、Spring Event都可以,可以根據實際需要選擇。其核心原理仍然是發布訂閱模式。

上述就是小編為大家分享的Spring中如何實現事務傳播了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

榕江县| 洛隆县| 喀喇| 德兴市| 岳阳市| 三亚市| 灵石县| 永和县| 曲周县| 浦北县| 长泰县| 晋州市| 东乡县| 彝良县| 东丰县| 陆丰市| 定结县| 河津市| 郯城县| 布拖县| 石家庄市| 揭阳市| 庄浪县| 城市| 湖北省| 永川市| 金阳县| 武隆县| 古丈县| 许昌县| 临沭县| 绥滨县| 宁武县| 礼泉县| 龙山县| 天台县| 青河县| 海阳市| 石景山区| 益阳市| 玉山县|