from:http://javatar.iteye.com/blog/981787
關(guān)于Dubbo服務(wù)框架的分布式事務(wù),雖然現(xiàn)在不急著做,但可以討論一下。
我覺(jué)得事務(wù)的管理不應(yīng)該屬于Dubbo框架,
Dubbo只需實(shí)現(xiàn)可被事務(wù)管理即可,
像JDBC和JMS都是可被事務(wù)管理的分布式資源,
Dubbo只要實(shí)現(xiàn)相同的可被事務(wù)管理的行為,比如可以回滾,
其它事務(wù)的調(diào)度,都應(yīng)該由專門的事務(wù)管理器實(shí)現(xiàn)。
在Java中,分布式事務(wù)主要的規(guī)范是JTA/XA,
其中:JTA是Java的事務(wù)管理器規(guī)范,
XA是工業(yè)標(biāo)準(zhǔn)的X/Open CAE規(guī)范,可被兩階段提交及回滾的事務(wù)資源定義,
比如某數(shù)據(jù)庫(kù)實(shí)現(xiàn)了XA規(guī)范,則不管是JTA,還是MSDTC,都可以基于同樣的行為對(duì)該數(shù)據(jù)庫(kù)進(jìn)行事務(wù)處理。
在JTA/XA中,主要有兩個(gè)擴(kuò)展點(diǎn):
(1) TransactionManager
JTA事務(wù)管理器接口,實(shí)現(xiàn)該接口,即可完成對(duì)所有XA資源的事務(wù)調(diào)度,比如BEA的Tuxedo,JBossJTA等。
(2) XAResource
XA資源接口,實(shí)現(xiàn)該接口,即可被任意TransactionManager調(diào)度,比如:JDBC的XAConnection,JMS的XAMQ等。
而Dubbo的遠(yuǎn)程服務(wù),也應(yīng)該是一個(gè)XAResource,比如:XAInvoker和XAExporter,
Dubbo只需在第一次提交時(shí),將請(qǐng)求發(fā)到服務(wù)提供方進(jìn)行緩存和寫盤,
在第二次提交時(shí),再基于緩存調(diào)用服務(wù)的Impl實(shí)現(xiàn),
當(dāng)然一些健狀性分支流程要考慮清楚。
JTA/XA的基本原理如下:
1. 用戶啟動(dòng)一個(gè)事務(wù):
2. 事務(wù)管理器在當(dāng)前線程中初始化一個(gè)事務(wù)實(shí)例:
3. 用戶調(diào)用JDBC或JMS或Dubbo請(qǐng)求,請(qǐng)求內(nèi)部初始化一個(gè)XAResource實(shí)例:
4. JDBC或JMS或Dubbo內(nèi)部從當(dāng)前線程獲取事務(wù):
5. 將當(dāng)前XAResource注冊(cè)到事務(wù)中:
6. 用戶提交一個(gè)事務(wù):
7. 事務(wù)for循環(huán)調(diào)用所有注冊(cè)的XAResource的兩階段提交:
8. 當(dāng)然,還有一些異常流程,比如rollback和forget等。
舉例:
關(guān)于Dubbo服務(wù)框架的分布式事務(wù),雖然現(xiàn)在不急著做,但可以討論一下。
我覺(jué)得事務(wù)的管理不應(yīng)該屬于Dubbo框架,
Dubbo只需實(shí)現(xiàn)可被事務(wù)管理即可,
像JDBC和JMS都是可被事務(wù)管理的分布式資源,
Dubbo只要實(shí)現(xiàn)相同的可被事務(wù)管理的行為,比如可以回滾,
其它事務(wù)的調(diào)度,都應(yīng)該由專門的事務(wù)管理器實(shí)現(xiàn)。
在Java中,分布式事務(wù)主要的規(guī)范是JTA/XA,
其中:JTA是Java的事務(wù)管理器規(guī)范,
XA是工業(yè)標(biāo)準(zhǔn)的X/Open CAE規(guī)范,可被兩階段提交及回滾的事務(wù)資源定義,
比如某數(shù)據(jù)庫(kù)實(shí)現(xiàn)了XA規(guī)范,則不管是JTA,還是MSDTC,都可以基于同樣的行為對(duì)該數(shù)據(jù)庫(kù)進(jìn)行事務(wù)處理。
在JTA/XA中,主要有兩個(gè)擴(kuò)展點(diǎn):
(1) TransactionManager
JTA事務(wù)管理器接口,實(shí)現(xiàn)該接口,即可完成對(duì)所有XA資源的事務(wù)調(diào)度,比如BEA的Tuxedo,JBossJTA等。
(2) XAResource
XA資源接口,實(shí)現(xiàn)該接口,即可被任意TransactionManager調(diào)度,比如:JDBC的XAConnection,JMS的XAMQ等。
而Dubbo的遠(yuǎn)程服務(wù),也應(yīng)該是一個(gè)XAResource,比如:XAInvoker和XAExporter,
Dubbo只需在第一次提交時(shí),將請(qǐng)求發(fā)到服務(wù)提供方進(jìn)行緩存和寫盤,
在第二次提交時(shí),再基于緩存調(diào)用服務(wù)的Impl實(shí)現(xiàn),
當(dāng)然一些健狀性分支流程要考慮清楚。
JTA/XA的基本原理如下:

1. 用戶啟動(dòng)一個(gè)事務(wù):
2. 事務(wù)管理器在當(dāng)前線程中初始化一個(gè)事務(wù)實(shí)例:
3. 用戶調(diào)用JDBC或JMS或Dubbo請(qǐng)求,請(qǐng)求內(nèi)部初始化一個(gè)XAResource實(shí)例:
4. JDBC或JMS或Dubbo內(nèi)部從當(dāng)前線程獲取事務(wù):
- Transaction transaction = transactionManager.getTransaction(); // 其內(nèi)部為:threadLocal.get();
5. 將當(dāng)前XAResource注冊(cè)到事務(wù)中:
6. 用戶提交一個(gè)事務(wù):
7. 事務(wù)for循環(huán)調(diào)用所有注冊(cè)的XAResource的兩階段提交:
- Xid xid = new XidImpl();
- for (XAResource xaResource: xaResources) {
- xaResource.prepare(xid);
- xaResource.commit(xid, true);
- xaResource.commit(xid, false);
- }
8. 當(dāng)然,還有一些異常流程,比如rollback和forget等。
舉例:
- TransactionManager transactionManager = ...; // 從JNDI進(jìn)行l(wèi)ookup等方式獲取
- transactionManager.begin(); // 啟動(dòng)事務(wù)
- try {
- jdbcConn.executeUpdate(sql); // 執(zhí)行SQL語(yǔ)句,DB寫入binlog,但不更新表
- jmsMQ.send(message); // 發(fā)送消息,MQ記錄消息,但不進(jìn)入隊(duì)列
- dubboService.invoke(parameters); // 調(diào)用遠(yuǎn)程服務(wù),Provider緩存請(qǐng)求信息,但不執(zhí)行
- transactionManager.commit(); // 提交事務(wù),數(shù)據(jù)庫(kù),消息隊(duì)列,遠(yuǎn)程服務(wù)同時(shí)提交
- } catch(Throwable t) {
- transactionManager.rollback(); // 回滾事務(wù),數(shù)據(jù)庫(kù),消息隊(duì)列,遠(yuǎn)程服務(wù)同時(shí)回滾
- }