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