分布式服务的事务如何处理?比如dubbo,服务与服务之间的事务怎么处理比较好,现在有没有开源的解决方案?...
生活随笔
收集整理的這篇文章主要介紹了
分布式服务的事务如何处理?比如dubbo,服务与服务之间的事务怎么处理比较好,现在有没有开源的解决方案?...
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
作者:何明璐
鏈接:http://www.zhihu.com/question/29483490/answer/98237582
來(lái)源:知乎
著作權(quán)歸作者所有,轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán)。
可以設(shè)想一個(gè)最簡(jiǎn)單的分布式事務(wù)場(chǎng)景,對(duì)于跨銀行的轉(zhuǎn)賬操作,該操作涉及到調(diào)用兩個(gè)異地的Service服務(wù),一個(gè)是本地提供的取款服務(wù),一個(gè)是目標(biāo)銀行提供的存款服務(wù),該兩個(gè)服務(wù)本身無(wú)狀態(tài)且獨(dú)立,構(gòu)成一個(gè)完整的事務(wù)。對(duì)于事務(wù)的處理初步分析:事務(wù)補(bǔ)償機(jī)制
事務(wù)補(bǔ)償即在事務(wù)鏈中的任何一個(gè)正向事務(wù)操作,都必須存在一個(gè)完全符合回滾規(guī)則的可逆事務(wù)。如果是一個(gè)完整的事務(wù)鏈,則必須事務(wù)鏈中的每一個(gè)業(yè)務(wù)服務(wù)或操作都有對(duì)應(yīng)的可逆服務(wù)。對(duì)于Service服務(wù)本身無(wú)狀態(tài),也不容易實(shí)現(xiàn)前面討論過(guò)的通過(guò)DTC或XA機(jī)制實(shí)現(xiàn)的跨應(yīng)用和資源的事務(wù)管理,建立跨資源的事務(wù)上下文。因此也較難以實(shí)現(xiàn)真正的預(yù)提交和正式提交的分離。
在這種情況下以上面例子來(lái)說(shuō),首先調(diào)用取款服務(wù),完全調(diào)用成功并返回,數(shù)據(jù)已經(jīng)持久化。然后調(diào)用異地的存款服務(wù),如果也調(diào)用成功,則本身無(wú)任何問(wèn)題。如果調(diào)用失敗,則需要調(diào)用本地注冊(cè)的逆向服務(wù)(本地存款服務(wù)),如果本地存款服務(wù)調(diào)用失敗,則必須考慮重試,如果約定重試次數(shù)仍然不成功,則必須log到完整的不一致信息。也可以是將本地存款服務(wù)作為消息發(fā)送到消息中間件,由消息中間件接管后續(xù)操作。
在上面方式中可以看到需要手工編寫(xiě)大量的代碼來(lái)處理以保證事務(wù)的完整性,我們可以考慮實(shí)現(xiàn)一個(gè)通用的事務(wù)管理器,實(shí)現(xiàn)事務(wù)鏈和事務(wù)上下文的管理。對(duì)于事務(wù)鏈上的任何一個(gè)服務(wù)正向和逆向操作均在事務(wù)管理和協(xié)同器上注冊(cè),由事務(wù)管理器接管所有的事務(wù)補(bǔ)償和回滾操作。基于消息的最終一致性
在這里首先要回答的是我們需要時(shí)實(shí)時(shí)一致性還是最終一致性的問(wèn)題,如果需要的是最終一致性,那么BASE策略中的基于消息的最終一致性是比較好的解決方案。這種方案真正實(shí)現(xiàn)了兩個(gè)服務(wù)的真正解耦,解耦的關(guān)鍵就是異步消息和消息持久化機(jī)制。
還是以上面的例子來(lái)看。對(duì)于轉(zhuǎn)賬操作,原有的兩個(gè)服務(wù)調(diào)用變化為第一步調(diào)用本地的取款服務(wù),第二步發(fā)送異地取款的異步消息到消息中間件。如果第二步在本地,則保證事務(wù)的完整性基本無(wú)任何問(wèn)題,即本身就是本地事務(wù)的管理機(jī)制。只要兩個(gè)操作都成功即可以返回客戶成功。
由于解耦,我們看到客戶得到成功返回的時(shí)候,如果是上面一種情況則異地卡馬上就能查詢賬戶存款增加。而第二種情況則不一定,因?yàn)楸旧硎且环N異步處理機(jī)制。消息中間件得到消息后會(huì)去對(duì)消息解析,然后調(diào)用異地銀行提供的存款服務(wù)進(jìn)行存款,如果服務(wù)調(diào)用失敗則進(jìn)行重試。
異地銀行存款操作不應(yīng)該長(zhǎng)久地出現(xiàn)異常而無(wú)法使用,因此一旦發(fā)現(xiàn)異常我們可以迅速的解決,消息中間件中異常服務(wù)自然會(huì)進(jìn)行重試以保證事務(wù)的最終一致性。這種方式假設(shè)問(wèn)題一定可以解決,在不到萬(wàn)不得已的情況下本地的取款服務(wù)一般不進(jìn)行可逆操作。
在本地取款到異地存款兩個(gè)服務(wù)調(diào)用之間,會(huì)存在一個(gè)真空期,這段時(shí)間相關(guān)現(xiàn)金不在任何一個(gè)賬戶,而只是在一個(gè)事務(wù)的中間狀態(tài),但是客戶并不關(guān)心這個(gè),只要在約定的時(shí)間保證事務(wù)最終的一致性即可。關(guān)于等冪操作的問(wèn)題
重復(fù)調(diào)用多次產(chǎn)生的業(yè)務(wù)結(jié)果與調(diào)用一次產(chǎn)生的業(yè)務(wù)結(jié)果相同,簡(jiǎn)單點(diǎn)講所有提供的業(yè)務(wù)服務(wù),不管是正向還是逆向的業(yè)務(wù)服務(wù),都必須要支持重試。因?yàn)榉?wù)調(diào)用失敗這種異常必須考慮到,不能因?yàn)榉?wù)的多次調(diào)用而導(dǎo)致業(yè)務(wù)數(shù)據(jù)的累計(jì)增加或減少。關(guān)于是否可以補(bǔ)償?shù)膯?wèn)題
在這里我們談的是多個(gè)跨系統(tǒng)的業(yè)務(wù)服務(wù)組合成一個(gè)分布式事務(wù),因此在對(duì)事務(wù)進(jìn)行補(bǔ)償?shù)臅r(shí)候必須要考慮客戶需要的是否一定是最終一致性。客戶對(duì)中間階段出現(xiàn)的不一致的承受度是如何的。
在上面的例子來(lái)看,如果采用事務(wù)補(bǔ)償機(jī)制,基本可以是做到準(zhǔn)實(shí)時(shí)的補(bǔ)償,不會(huì)有太大的影響。而如果采用基于消息的最終一致性方式,則可能整個(gè)周期比較長(zhǎng),需要較長(zhǎng)的時(shí)間才能給得到最終的一致性。比如周六轉(zhuǎn)款,客戶可能下周一才得到通知轉(zhuǎn)賬不成功而進(jìn)行了回退,那么就必須要考慮客戶是否能給忍受。
其次對(duì)于前面討論,如果真正需要的是實(shí)時(shí)的一致性,那么即使采用事務(wù)補(bǔ)償機(jī)制,也無(wú)法達(dá)到實(shí)時(shí)的一致性。即很可能在兩個(gè)業(yè)務(wù)服務(wù)調(diào)用中間,客戶前臺(tái)業(yè)務(wù)操作對(duì)持久化的數(shù)據(jù)進(jìn)行了其它額外的操作。在這種模式下,我們不得不考慮需要在數(shù)據(jù)庫(kù)表增加業(yè)務(wù)狀態(tài)鎖的問(wèn)題,即整個(gè)事務(wù)沒(méi)有完整提交并成功前,第一個(gè)業(yè)務(wù)服務(wù)調(diào)用雖然持久化在數(shù)據(jù)庫(kù),但是仍然是一個(gè)中間狀態(tài),需要通過(guò)業(yè)務(wù)鎖來(lái)標(biāo)記,控制相關(guān)的業(yè)務(wù)操作和行為。但是在這種模式下無(wú)疑增加了整個(gè)分布式業(yè)務(wù)系統(tǒng)的復(fù)雜度。
關(guān)于SOA分布式事務(wù)情況參考:http://wenku.baidu.com/view/be946bec0975f46527d3e104.html
總結(jié)
以上是生活随笔為你收集整理的分布式服务的事务如何处理?比如dubbo,服务与服务之间的事务怎么处理比较好,现在有没有开源的解决方案?...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 普通人安全生产要注意什么(普通人怎么被星
- 下一篇: 如何培养孩子自主阅读(如何培养孩子的阅读