本篇內(nèi)容介紹了“如何在spring事務(wù)中正確進(jìn)行遠(yuǎn)程調(diào)用”的有關(guān)知識,在實(shí)際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

冷水灘ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:13518219792(備注:SSL證書合作)期待與您的合作!
最近和朋友聊天,他說他承接的外包項(xiàng)目遇到了分布式事務(wù)問題,問我有沒啥解決方案,我本可以直接跟他說,分布式事務(wù)方案網(wǎng)上一大堆,什么tcc、可靠消息一致性、最大努力通知之類的,直接網(wǎng)上找個(gè)試下,比如直接用阿里的seata。但我并沒有這么做,因?yàn)榉植际绞聞?wù),本來就是一個(gè)很復(fù)雜的課題,真正落地的時(shí)候,會發(fā)現(xiàn)有時(shí)候是多種分布式方案一起混用,而非一種方案走到黑。
因此我就跟他說,能不用分布式事務(wù),就盡量不用,后來我就問了一下他的業(yè)務(wù)場景,場景也不是很復(fù)雜,就是邀請好友注冊,然后可以增加積分,朋友實(shí)現(xiàn)邏輯的偽代碼大概如下
@Transactional(rollbackFor = Exception.class)
public Boolean inviteUser(..){
userService.add(..);
integralService.addIntegration(..,20)
}其中integralService是一個(gè)遠(yuǎn)程積分服務(wù),20為增加的積分值。這代碼乍一看是沒問題,我想可能很多朋友都會這么寫。后邊我就問朋友說你們這個(gè)業(yè)務(wù)場景是否允許如下場景
允不允許邀請的用戶入庫成功,而積分入庫失敗?
允不允許邀請的用戶入庫失敗,而積分入庫成功?
朋友思考了一下,說第二種不允許,第一種方式可以通過補(bǔ)償?shù)姆绞皆黾臃e分。
現(xiàn)在我們回過頭來看這段代碼,我拋出以下兩個(gè)問題,看文章的朋友可以思考下
如果添加積分請求耗時(shí)特別長,這段代碼有沒有問題?
如果添加積分因?yàn)榫W(wǎng)絡(luò)抖動原因出了異常,這段代碼有沒有問題?
這邊說下我的想法
耗時(shí)過長,會導(dǎo)致長事務(wù)的發(fā)生,在并發(fā)場景下,可能會導(dǎo)致數(shù)據(jù)庫連接得不到釋放
網(wǎng)絡(luò)抖動出了異常,可能會導(dǎo)致用戶服務(wù)的添加邏輯進(jìn)行回滾
解決耗時(shí)過長,有些朋友可能想到可以采用異步的方式,積分抖動異常,可以通過添加熔斷機(jī)制,比如積分超時(shí)沒響應(yīng),就直接進(jìn)行熔斷
今天我再說一種方案,就是在事務(wù)提交后再進(jìn)行調(diào)用,羅里吧嗦一大堆,才剛要進(jìn)入正題,哈哈
這個(gè)是個(gè)什么鬼,這是我直譯,它的真身是長如下
org.springframework.transaction.support.TransactionSynchronizationManager
這玩意有啥用,可以利用它注冊一個(gè)事務(wù)同步器,這個(gè)事務(wù)同步器,可以允許在事務(wù)提交后,做一些事情,核心代碼如下
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
//做你想做的業(yè)務(wù)
}
});看了代碼,想必大家都知道怎么改造上面邀請用戶,添加積分了吧
@Transactional(rollbackFor = Exception.class)
public Boolean inviteUser(..) {
userService.add(..);
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
integralService.addIntegration(..,20)
}
});但大家發(fā)現(xiàn)沒有,每次都要寫這么一坨代碼,看著是不是很惡心,有沒有什么改造的方案。 答案有的,通過注解+aop來整合實(shí)現(xiàn),具體實(shí)現(xiàn)邏輯,可以查看下面demo鏈接中的
com.github.lybgeek.transactional
我這邊就不貼具體代碼了,為什么不貼,是因?yàn)槲乙榻B另外一種方案,就是基于spring的事件驅(qū)動實(shí)現(xiàn)
這是spring的事件驅(qū)動實(shí)現(xiàn),或者說是觀察者實(shí)現(xiàn)方式,不過TransactionalEventListener注解是spring4.2版本之后才提供的注解
通過這種方式如何改造上面邀請用戶,添加積分的實(shí)現(xiàn)?
1、在邀請用戶注冊方法中,進(jìn)行事件發(fā)布
偽代碼如下
@Transactional(rollbackFor = Exception.class)
public Boolean inviteUser(..) {
userService.add(..);
applicationEventPublisher.publishEvent(..);
});2、編寫一個(gè)事務(wù)監(jiān)聽器,并在里面觸發(fā)添加積分實(shí)現(xiàn)
偽代碼如下
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void addIntegration(..){
integralService.addIntegration(..,20)
}這邊有個(gè)細(xì)節(jié)點(diǎn)要注意,就是監(jiān)聽事件的參數(shù)要和發(fā)布的參數(shù)一致
3、實(shí)現(xiàn)核心源碼
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (TransactionSynchronizationManager.isSynchronizationActive()) {
TransactionSynchronization transactionSynchronization = createTransactionSynchronization(event);
TransactionSynchronizationManager.registerSynchronization(transactionSynchronization);
}
else if (this.annotation.fallbackExecution()) {
if (this.annotation.phase() == TransactionPhase.AFTER_ROLLBACK && logger.isWarnEnabled()) {
logger.warn("Processing " + event + " as a fallback execution on AFTER_ROLLBACK phase");
}
processEvent(event);
}
else {
// No transactional event execution at all
if (logger.isDebugEnabled()) {
logger.debug("No transaction is active - skipping " + event);
}
}
}不知道大家發(fā)現(xiàn)沒有,他本質(zhì)上還是使用了TransactionSynchronizationManager,只是對他再一次進(jìn)行封裝
在和朋友交流后,發(fā)現(xiàn)他們那個(gè)外包項(xiàng)目開發(fā)人員就只有三個(gè),然后服務(wù)拆分了10來個(gè),我就問他說這個(gè)外包項(xiàng)目業(yè)務(wù)有很復(fù)雜嗎,他說其實(shí)還好,我就問他說業(yè)務(wù)不復(fù)雜,開發(fā)人員也不多,為什么不用單體架構(gòu),而要用微服務(wù)。他給我的答案是甲方爸爸覺得他們項(xiàng)目未來會承載很大的業(yè)務(wù)量,所以必須得用微服務(wù),而且現(xiàn)在的主流技術(shù)棧是微服務(wù)。聽到這個(gè)答復(fù),我是該說是過度設(shè)計(jì)還是高瞻遠(yuǎn)矚呢?技術(shù)日新月異,鬼知道后面會不會出現(xiàn)更厲害的東西,架構(gòu)從來都不是一步到位,而是逐步演進(jìn)
https://github.com/lyb-geek/springboot-learning/tree/master/springboot-transation-after-commit
“如何在spring事務(wù)中正確進(jìn)行遠(yuǎn)程調(diào)用”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
分享名稱:如何在spring事務(wù)中正確進(jìn)行遠(yuǎn)程調(diào)用
網(wǎng)站路徑:http://www.chinadenli.net/article20/gicgco.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)、電子商務(wù)、品牌網(wǎng)站建設(shè)、商城網(wǎng)站、做網(wǎng)站、App開發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)