生活随笔
收集整理的這篇文章主要介紹了
将非事务性资源绑定到JTA事务中的几种模式
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
我最近發表了一篇有關如何將非事務性資源(如Web服務/微服務)綁定到全局分布式事務中的文章,以便自動處理恢復。 多年來,我經常不得不將“非事務性”系統集成到Java EE應用程序服務器中,而數據一致性通常是討論的話題,甚至是非功能性需求。 我將“非事務性”用引號引起來,因為通常系統包含確保數據一致性的方法,例如使用調用進行補償,但是這些系統通常不是您傳統上稱為事務性的。 當然,無法將Java EE應用程序服務器配置為自動處理此類資源的恢復。
以下是我們編譯的模式列表,顯示了面對集成非事務系統的任務時保持一致性的不同方法。
將作業寫入數據庫 –常見的情況是您要在出售后向您發送一封電子郵件確認信。 您無法發送電子郵件,然后嘗試將銷售交易提交到數據庫,因為如果提交失敗,則客戶會收到一封電子郵件,指出他們已經購買了商品,并且您沒有任何記錄。 將銷售交易提交到數據庫后,您將無法發送電子郵件,因為如果電子郵件發送失敗(例如,郵件服務器暫時關閉),則客戶將無法獲得其確認,也許會帶有指向票證的鏈接他們買了。 一種解決方案是將需要發送電子郵件的事實寫入持久銷售的同一筆交易中。 然后,批處理或@Scheduled EJB可以定期檢查以查看是否應發送電子郵件。 成功發送電子郵件后,它將更改記錄的狀態,以便不再發送電子郵件。 同樣的問題在這里適用,您可能只能發送電子郵件,而不能更新數據庫。 但是,如果您能夠讀取數據庫,則很可能能夠對其進行更新,并且由于數據庫故障而發送兩次相同的電子郵件不會像從不發送郵件那樣糟糕,就像您未曾發送郵件一樣。處理異步發送電子郵件。 像這樣進行集成的一個缺點是,這意味著您無法集成需要結果的系統,以便在答復用戶之前繼續處理業務邏輯。 您必須異步處理集成。 JMS –在與先前解決方案類似的情況下,您可以發送包含作業的JMS消息,而不是將作業寫入數據庫。 JMS是事務性的,但是是異步的,因此該解決方案具有與上述解決方案相同的缺點。 如果您當時無法處理工作,則無需更改待完成的工作狀態,而是將消息發送到帶有屬性的隊列中,以便僅在一定時間后處理該消息,或者發送消息發送到死信隊列以進行手動處理。 通用連接器(JCA適配器) –我最近發表了一篇博客文章,描述了我創建的通用JCA資源適配器,該適配器可讓您通常將非事務性資源(如Web服務)綁定到JTA事務中。 有關更多詳細信息,請參見博客文章。 使用通用連接器意味著事務管理器將在需要提交,回滾或恢復事務時執行回調,因此您只需要編寫響應這些事件的應用程序代碼即可。 CDI事件 –在字段和字段上使用@Inject @Qualifier Event<T> field.fire(t); 當您要在方法參數上觸發事件&@ @Observes(during=TransactionPhase.AFTER_FAILURE) @Qualifier T時,在事務失敗后,將為每個觸發的事件調用該方法。 這樣,您可以對事務失敗時進行一些補償。 同樣,您可以使用不同的交易階段來執行不同的操作,例如AFTER_SUCCESS來執行呼叫以確認初始預訂。 我們甚至使用了這些機制來延遲對遠程系統的調用,例如在提交之前將工作發布到工作流引擎,以便確保在遠程系統調用完成之前,復雜過程中的所有驗證邏輯都已完成。制作。 請參閱下面的數字12。 定制解決方案 –如果您真的可以證明其合理性,則可以構建帶有超時等內容的復雜代碼,其中涉及批處理和腳本,這些批處理和腳本使用遠程資源來處理提交,回滾和恢復事務。 您需要問自己的問題是您是編寫業務代碼方面的專家還是有效編寫事務管理器方面的專家。 業務流程引擎 –現代引擎可以將各種遠程資源集成到業務流程中,并且它們傾向于處理故障恢復之類的事情。 他們通常重試失敗的呼叫,并且在遠程系統再次聯機之前,它們可以持久地處理流程狀態,以便可以恢復流程。 BPEL支持補償以確保整個環境的一致性,而不是提交和回滾。 Atomikos&TCC –一種能夠將Web服務綁定到JTA交易中的產品。 據我所知,它是一個獨立的事務管理器,可以在Java EE應用程序服務器之外運行。 但是我沒有這個產品的經驗。 WS-AT –使用專有配置(和/或注釋),您可以設置兩個應用程序服務器以在全局事務中完成其工作。 盡管這聽起來很有希望,但我還沒有遇到實現WS-AT的高效系統。 盡管JBoss正在準備支持REST服務的管道 ,但實際上僅支持SOAP Web服務。 EJB –遠程EJB:Java EE應用程序服務器能夠在較長時間內將事務上下文從一臺服務器傳播到另一臺服務器。 如果您需要調用恰巧是使用Java EE堆棧實現的服務,為什么不使用遠程EJB而不是通過Web服務調用它來進行調用,以便將服務免費綁定到全局事務中呢?
–本地EJB:如果您要調用的服務恰好是使用EJB技術用Java編寫的,為什么不只是在本地部署它,而不是花更多的精力通過SOAP Web服務進行遠程調用呢? 您可能會從企業架構師那里獲得布朗尼點,但是可擴展性和可組合性是否已與性能,一致性和簡單性進行了比較? 當然,具有微服務趨勢的現代架構意味著部署許多遠程服務是件好事,但是總要權衡取舍,并且在決定需要遠程訪問景觀的哪些部分時需要真正理解它。 事務回調 –與解決方案4類似,但使用事務同步 API注冊在事務相關階段調用的回調。 與CDI事件不同,這里的問題是您不知道在其中提交或回滾事務的上下文,因為不像在CDI中傳遞給觀察方法的對象那樣,回調不傳遞相關數據。 。 因此,如果您需要補償交易并致電說一個Web服務來取消您在交易期間所做的操作,那么您將在何處獲取所需的數據呢? 將XA資源注冊到事務中 –添加XAResource接口的自定義實現,您可以使用enlistResource方法將其enlistResource到事務中。 不幸的是,commit / rollback方法僅被調用一次,如果它們失敗了,在恢復過程中將不會被再次調用。 最后是非事務性資源 –如果無法實現其他模式,并且您不需要在流程中的特定時間調用資源,例如,您需要發送電子郵件作為交易的一部分,但是不需要不管您是在第一步還是最后一個步驟中執行此操作,都必須始終在流程結束時(即在提交事務之前)立即調用它。 與遠程系統調用失敗的機會相比,事務無法提交的機會相對較小(特別是如果所有SQL已刷新到數據庫中的情況)。 如果調用失敗,則回滾事務。 如果調用成功,則提交事務。 如果事務然后在提交期間失敗,并且對您補償非事務性資源很重要,那么您將需要使用上述模式之一向系統添加一些補償。 下表總結了解決方案。 恢復列指示此解決方案支持的自動恢復級別。 同步性列指示如果需要響應以繼續處理,是否可以使用解決方案,在這種情況下,您需要同步解決方案。 這里的同步與阻塞與非阻塞無關,而是與計時以及是否需要響應才能完成活動的處理有關。
解 同步性 復蘇
| 1)將作業寫入數據庫 | 異步 | 手冊1 |
| 2)JMS | 異步 | 半自動2 |
| 3)通用連接器(JCA適配器) | 同步 | 自動3 |
| 4)CDI活動 | 異步 | 不支持4 |
| 5)定制解決方案 | 取決于您的實現 | 取決于您的實現 |
| 6)業務流程引擎 | 同步 | 支持5 |
| 7)Atomikos和TCC | 沒有經驗,大概是同步的 | 沒有經驗,大概支持 |
| 8)WS-AT(配置) | 沒有經驗,大概是同步的 | 沒有經驗,大概支持 |
| 9)EJB | 同步 | 自動6 |
| 10)交易回調 | 同步 | 不支持4 |
| 11)招募XA資源進行交易 | 同步 | 不支持4 |
| 12)非交易資源排在最后 | 異步,因為必須最后調用 | 不支持 |
腳注:
手動恢復–您需要編程處理失敗時的處理方式,即在將工作置于“死信隊列”之前應嘗試重試的頻率。 如果將隊列配置為持久性,JMS將自動嘗試重新發送消息。 但是,程序員嘗試處理失敗的消息將由您自己決定。 事務管理器將不斷嘗試提交/回滾未完成的事務,直到管理員介入以處理長時間運行的故障為止。 回調僅被調用一次,因此您只有一次機會 業務流程引擎將反復嘗試重新調用失敗的Web服務調用。 補償也是如此。 該行為通常是可配置的。 遠程EJB:JTA事務跨其他應用服務器傳播,因此協調事務管理器會將事務恢復傳播到綁定到該事務的其他應用服務器。
本地EJB:使用本地EJB意味著它們對數據庫的任何調用都將在與應用程序代碼相同的事務中處理。 如果本地EJB使用其他數據庫,則應對所有數據庫,消息隊列等使用XA驅動程序,以便事務管理器可以使用兩階段提交來確保系統范圍的一致性。 在所有這些中,我目前最喜歡的是通用連接器 。 它支持需要響應的呼叫以及完全自動的恢復。 這意味著我可以專注于編寫業務代碼,而不是真正屬于框架的樣板代碼。
如果您知道其他方法,請與我聯系或發表評論,以便我可以將它們添加到列表中。
翻譯自: https://www.javacodegeeks.com/2015/08/several-patterns-for-binding-non-transactional-resources-into-jta-transactions.html
總結
以上是生活随笔為你收集整理的将非事务性资源绑定到JTA事务中的几种模式的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。