還是我經(jīng)常說(shuō)的那句話,沒(méi)有分布式,Java其實(shí)挺簡(jiǎn)單,一有分布式,所有的問(wèn)題都需要考慮一遍,變引發(fā)了各種系統(tǒng)性的架構(gòu)演變,一切都是分布式惹的禍!
現(xiàn)在考慮一個(gè)問(wèn)題:
訂單提交:
@Transactional
public void submitOrder(){
1 、 生成訂單
2、 鎖定庫(kù)存
3、 扣用戶積分
}
這個(gè)方法中有三個(gè)邏輯,每個(gè)邏輯都是一個(gè)很復(fù)雜的方法,如果方法出現(xiàn)異常,變回滾,貌似是沒(méi)有問(wèn)題的,但仔細(xì)想想會(huì)出現(xiàn)以下問(wèn)題:

1、遠(yuǎn)程服務(wù)假失敗
遠(yuǎn)程服務(wù)成功了,但是由于網(wǎng)絡(luò)原因沒(méi)有返回?cái)?shù)據(jù)導(dǎo)致訂單回滾,庫(kù)存卻扣減。
2、遠(yuǎn)程服務(wù)區(qū)執(zhí)行成功,后面的方法出現(xiàn)問(wèn)題,導(dǎo)致已執(zhí)行的遠(yuǎn)程請(qǐng)求不能回滾。
所以必須使用分布式事務(wù)才能解決!
回顧本地事務(wù),以防面試問(wèn)到:

事務(wù)還有傳播機(jī)制等,說(shuō)的是一個(gè)方法調(diào)用了其他方法,其他方法是否使用該方法的事務(wù)。
本地事務(wù)中springboot有一個(gè)非常好的注解@Transactional ,但有一個(gè)漏洞需要說(shuō)明一下,看示例代碼:
public void a(){
b();
c();
}

a方法設(shè)置了事務(wù)的傳播機(jī)制以及過(guò)期時(shí)間等諸多設(shè)置,b,c 方法也有自己的事務(wù)的設(shè)置選項(xiàng),如果b方法和c方法和a同在一個(gè)service類(lèi)中,那么b和c方法設(shè)置的事務(wù)是無(wú)效的,如果b和c是其他類(lèi)中的方法,設(shè)置是有效的。
如何解決這個(gè)問(wèn)題呢?
就是使用代理機(jī)制。

通過(guò)aop中的aspectJ創(chuàng)建代理對(duì)象,然后通過(guò)代理對(duì)象調(diào)用本地的方法,便可以成功解決。
這里需要復(fù)習(xí)spring 動(dòng)態(tài)代理和jdk動(dòng)態(tài)代理的區(qū)別。