分布式事務(wù)

1、線程安全
保證線程安全一般分成兩種方式:鎖和原子變量
原子變量:原子變量能夠保證原子性的操作,意思是某個(gè)任務(wù)在執(zhí)行過(guò)程中,要么全部成功,要么全部失敗回滾,恢復(fù)到執(zhí)行之前的初態(tài),不存在初態(tài)和成功之間的中間狀態(tài)。
例如CAS操作,要么比較并交換成功,要么比較并交換失敗。由CPU保證原子性。通過(guò)原子變量可以實(shí)現(xiàn)線程安全。一般會(huì)通過(guò)while/for循環(huán)來(lái)重新執(zhí)行,直到賦值成功。
在高度競(jìng)爭(zhēng)的情況下,鎖的性能將超過(guò)原子變量的性能,但是更真實(shí)的競(jìng)爭(zhēng)情況下,原子變量的性能將超過(guò)鎖的性能。

2、disruptor
https://tech.meituan.com/2016/11/18/disruptor.html

分布式事務(wù):
剛性事務(wù):
2PC/3PC (XA)
缺點(diǎn):性能差、資源占用時(shí)間長(zhǎng)、需要實(shí)現(xiàn)XA接口
柔性事務(wù):
異步確保型
缺點(diǎn):侵入性高、實(shí)時(shí)性差
純補(bǔ)償型
缺點(diǎn):侵入性高、開(kāi)發(fā)成本高、一致性差
TCC
缺點(diǎn)“侵入性高、開(kāi)發(fā)成本高
最大努力通知
缺點(diǎn):侵入性高、開(kāi)發(fā)成本高、實(shí)時(shí)性差

Seata:
Ali 微服務(wù)架構(gòu)下的分布式事務(wù)

XA:
XA是一個(gè)分布式事務(wù)協(xié)議,由Tuxedo提出。
XA中大致分為兩部分:事務(wù)管理器和本地資源管理器。其中本地資源管理器往往由數(shù)據(jù)庫(kù)實(shí)現(xiàn),比如Oracle、DB2這些商業(yè)數(shù)據(jù)庫(kù)都實(shí)現(xiàn)了XA接口,而事務(wù)管理器作為全局的調(diào)度者,負(fù)責(zé)各個(gè)本地資源的提交和回滾。
即,XA是一個(gè)協(xié)議,一套接口

2PC:
兩階段提交協(xié)議(The two-phase commit protocol,2PC)是XA用于在全局事務(wù)中協(xié)調(diào)多個(gè)資源的機(jī)制。
即,2PC 是一套XA用于實(shí)現(xiàn)分布式事務(wù)的機(jī)制,即具體實(shí)現(xiàn)方案。

//假設(shè)有兩個(gè)庫(kù),userDB, transactionDB

//注冊(cè)JDBC驅(qū)動(dòng)
Class.forName(JDBC_DRIVER);
//打開(kāi)連接
userDbConn=DriverManager.getConnection(USER_DB_URL, USER, PASS);
XAConnection xaUserConn = new MysqlXAConnection((com.mysql.jdbc.Connection), userDbConnn, logXaCommands);
XAResource rmUser = xaUserConn.getXAResource();

transDbConn=DriverManager.getConnection(TRANS_DB_URL, USER, PASS);
XAConnection xaTransConn = new MysqlXAConnection((com.mysql.jdbc.Connection), transDbConnn, logXaCommands);
XAResource rmTrans = xaTransConn.getXAResource();

//AP 請(qǐng)求TM執(zhí)行一個(gè)分布式事務(wù) ,TM生成全局事務(wù)id
byte[] gTRID="g12345".getBytes(); //全局事務(wù)id
int formatId = 1;

//分別執(zhí)行 rmUser, rmTrans上的事務(wù)分支

//TM 生成rmTrans上的事務(wù)分支id
byte[] transid = "b00001".getBytes();
Xid xid1 = new MysqlXid(gtrid, transid, formatId);
//執(zhí)行rmTrans上的事務(wù)分支
rmTrans.start(xid1, XAResource.TMNOFLAGS);
PreparedStateement insertSql = transDbConn.prepareStatement("insert int transTable ....");
insertSql.executeUpdate();
rmTrans.end(xid1, XAResource.TMSUCCESS);

//TM生成rmUser上的事務(wù)分支
byte[] user_id = "b00002".getBytes();
Xid xid2 = new MysqlXid(gtrid, user_id, formatId);
//執(zhí)行userTrans上的事務(wù)分支
rmUser.start(xid1, XAResource.TMNOFLAGS);
PreparedStateement updateSql = userDbConn.prepareStatement("update Seller .....");
updateSql.executeUpdate();
rmUser.end(xid2, XAResource.TMSUCCESS);

//兩階段提交
//phase1:詢問(wèn)所有的RM準(zhǔn)備提交事務(wù)分支
int rmTrans_prepare = rmTrans.prepare(xid1);
int rmUser_prepare = rmUser.prepare(xid2);

//phase2:提交所有分支
boolean onPhase = false; //T判斷有2個(gè)事務(wù)分支看所以不能優(yōu)化為一階段提交

if(rmTrans_prepare == XAResoure.XA_OK && rmUser_prepare == XAResource.XA_ok) {
//所有事務(wù)分之 都prepare成功,提交所有事務(wù)分支
rmTrans.commit(xid1, onephase);
rmUser.commint(xid2, onePhase);
} else {
rmTrans.rollback(xid1);
rmUser.rollback(xid2);
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容