精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

讓人頭痛的大事務問題到底要如何解決?

開發 項目管理
正好前段時間我在公司處理過這個問題,我們當時由于項目初期時間比較緊張,為了快速完成業務功能,忽略了系統部分性能問題。

[[354795]]

本文轉載自微信公眾號「蘇三說技術」,作者因為熱愛所以堅持ing。轉載本文請聯系蘇三說技術公眾號。   

前言

最近有個網友問了我一個問題:系統中大事務問題要如何處理?

正好前段時間我在公司處理過這個問題,我們當時由于項目初期時間比較緊張,為了快速完成業務功能,忽略了系統部分性能問題。項目順利上線后,專門抽了一個迭代的時間去解決大事務問題,目前已經優化完成,并且順利上線。現給大家總結了一下,我們當時使用的一些解決辦法,以便大家被相同問題困擾時,可以參考一下。

大事務引發的問題

在分享解決辦法之前,先看看系統中如果出現大事務可能會引發哪些問題

 

從上圖可以看出如果系統中出現大事務時,問題還不小,所以我們在實際項目開發中應該盡量避免大事務的情況。如果我們已有系統中存在大事務問題,該如何解決呢?

解決辦法

少用@Transactional注解

大家在實際項目開發中,我們在業務方法加上@Transactional注解開啟事務功能,這是非常普遍的做法,它被稱為聲明式事務。

部分代碼如下:

  1. @Transactional(rollbackFor=Exception.class) 
  2.   public void save(User user) { 
  3.         doSameThing... 
  4.   } 

然而,我要說的第一條是:少用@Transactional注解。

為什么?

  1. 我們知道@Transactional注解是通過spring的aop起作用的,但是如果使用不當,事務功能可能會失效。如果恰巧你經驗不足,這種問題不太好排查。至于事務哪些情況下會失效,可以參考我之前寫的《spring事務的這10種坑,你稍不注意可能就會踩中!!!》這篇文章。
  2. @Transactional注解一般加在某個業務方法上,會導致整個業務方法都在同一個事務中,粒度太粗,不好控制事務范圍,是出現大事務問題的最常見的原因。

那我們該怎么辦呢?

可以使用編程式事務,在spring項目中使用TransactionTemplate類的對象,手動執行事務。

部分代碼如下:

  1. @Autowired 
  2.    private TransactionTemplate transactionTemplate; 
  3.     
  4.    ... 
  5.     
  6.    public void save(final User user) { 
  7.          transactionTemplate.execute((status) => { 
  8.             doSameThing... 
  9.             return Boolean.TRUE
  10.          }) 
  11.    } 

從上面的代碼中可以看出,使用TransactionTemplate的編程式事務功能自己靈活控制事務的范圍,是避免大事務問題的首選辦法。

當然,我說少使用@Transactional注解開啟事務,并不是說一定不能用它,如果項目中有些業務邏輯比較簡單,而且不經常變動,使用@Transactional注解開啟事務開啟事務也無妨,因為它更簡單,開發效率更高,但是千萬要小心事務失效的問題。

將查詢(select)方法放到事務外

如果出現大事務,可以將查詢(select)方法放到事務外,也是比較常用的做法,因為一般情況下這類方法是不需要事務的。

比如出現如下代碼:

  1. @Transactional(rollbackFor=Exception.class) 
  2.    public void save(User user) { 
  3.          queryData1(); 
  4.          queryData2(); 
  5.          addData1(); 
  6.          updateData2(); 
  7.    } 

可以將queryData1和queryData2兩個查詢方法放在事務外執行,將真正需要事務執行的代碼才放到事務中,比如:addData1和updateData2方法,這樣就能有效的減少事務的粒度。

如果使用TransactionTemplate的編程式事務這里就非常好修改。

  1. @Autowired 
  2.    private TransactionTemplate transactionTemplate; 
  3.     
  4.    ... 
  5.     
  6.    public void save(final User user) { 
  7.          queryData1(); 
  8.          queryData2(); 
  9.          transactionTemplate.execute((status) => { 
  10.             addData1(); 
  11.             updateData2(); 
  12.             return Boolean.TRUE
  13.          }) 
  14.    } 

但是如果你實在還是想用@Transactional注解,該怎么拆分呢?

  1. public void save(User user) { 
  2.          queryData1(); 
  3.          queryData2(); 
  4.          doSave(); 
  5.     } 
  6.     
  7.     @Transactional(rollbackFor=Exception.class) 
  8.     public void doSave(User user) { 
  9.        addData1(); 
  10.        updateData2(); 
  11.     } 

這個例子是非常經典的錯誤,這種直接方法調用的做法事務不會生效,給正在坑中的朋友提個醒。因為@Transactional注解的聲明式事務是通過spring aop起作用的,而spring aop需要生成代理對象,直接方法調用使用的還是原始對象,所以事務不會生效。

有沒有辦法解決這個問題呢?

1.新加一個Service方法

這個方法非常簡單,只需要新加一個Service方法,把@Transactional注解加到新Service方法上,把需要事務執行的代碼移到新方法中。具體代碼如下:

  1. @Servcie 
  2.   public class ServiceA { 
  3.      @Autowired 
  4.      prvate ServiceB serviceB; 
  5.    
  6.      public void save(User user) { 
  7.            queryData1(); 
  8.            queryData2(); 
  9.            serviceB.doSave(user); 
  10.      } 
  11.    } 
  12.     
  13.    @Servcie 
  14.    public class ServiceB { 
  15.     
  16.       @Transactional(rollbackFor=Exception.class) 
  17.       public void doSave(User user) { 
  18.          addData1(); 
  19.          updateData2(); 
  20.       } 
  21.     
  22.    } 

2.在該Service類中注入自己

如果不想再新加一個Service類,在該Service類中注入自己也是一種選擇。具體代碼如下:

  1. @Servcie 
  2.   public class ServiceA { 
  3.      @Autowired 
  4.      prvate ServiceA serviceA; 
  5.    
  6.      public void save(User user) { 
  7.            queryData1(); 
  8.            queryData2(); 
  9.            serviceA.doSave(user); 
  10.      } 
  11.       
  12.      @Transactional(rollbackFor=Exception.class) 
  13.      public void doSave(User user) { 
  14.          addData1(); 
  15.          updateData2(); 
  16.       } 
  17.    } 

可能有些人可能會有這樣的疑問:這種做法會不會出現循環依賴問題?

其實spring ioc內部的三級緩存保證了它,不會出現循環依賴問題。如果你想進一步了解循環依賴問題,可以看看我之前文章《spring解決循環依賴為什么要用三級緩存?》。

3.在該Service類中使用AopContext.currentProxy()獲取代理對象

上面的方法2確實可以解決問題,但是代碼看起來并不直觀,還可以通過在該Service類中使用AOPProxy獲取代理對象,實現相同的功能。具體代碼如下:

  1. @Servcie 
  2.   public class ServiceA { 
  3.    
  4.      public void save(User user) { 
  5.            queryData1(); 
  6.            queryData2(); 
  7.            ((ServiceA)AopContext.currentProxy()).doSave(user); 
  8.      } 
  9.       
  10.      @Transactional(rollbackFor=Exception.class) 
  11.      public void doSave(User user) { 
  12.          addData1(); 
  13.          updateData2(); 
  14.       } 
  15.    } 

事務中避免遠程調用

我們在接口中調用其他系統的接口是不能避免的,由于網絡不穩定,這種遠程調的響應時間可能比較長,如果遠程調用的代碼放在某個事物中,這個事物就可能是大事務。當然,遠程調用不僅僅是指調用接口,還有包括:發MQ消息,或者連接redis、mongodb保存數據等。

  1. @Transactional(rollbackFor=Exception.class) 
  2.    public void save(User user) { 
  3.          callRemoteApi(); 
  4.          addData1(); 
  5.    } 

遠程調用的代碼可能耗時較長,切記一定要放在事務之外。

  1. @Autowired 
  2.    private TransactionTemplate transactionTemplate; 
  3.     
  4.    ... 
  5.     
  6.    public void save(final User user) { 
  7.          callRemoteApi(); 
  8.          transactionTemplate.execute((status) => { 
  9.             addData1(); 
  10.             return Boolean.TRUE
  11.          }) 
  12.    } 

有些朋友可能會問,遠程調用的代碼不放在事務中如何保證數據一致性呢?這就需要建立:重試+補償機制,達到數據最終一致性了。

事務中避免一次性處理太多數據

如果一個事務中需要處理的數據太多,也會造成大事務問題。比如為了操作方便,你可能會一次批量更新1000條數據,這樣會導致大量數據鎖等待,特別在高并發的系統中問題尤為明顯。

解決辦法是分頁處理,1000條數據,分50頁,一次只處理20條數據,這樣可以大大減少大事務的出現。

非事務執行

在使用事務之前,我們都應該思考一下,是不是所有的數據庫操作都需要在事務中執行?

  1. @Autowired 
  2.    private TransactionTemplate transactionTemplate; 
  3.     
  4.    ... 
  5.     
  6.    public void save(final User user) { 
  7.          transactionTemplate.execute((status) => { 
  8.             addData(); 
  9.             addLog(); 
  10.             updateCount(); 
  11.             return Boolean.TRUE
  12.          }) 
  13.    } 

上面的例子中,其實addLog增加操作日志方法 和 updateCount更新統計數量方法,是可以不在事務中執行的,因為操作日志和統計數量這種業務允許少量數據不一致的情況。

  1. @Autowired 
  2.    private TransactionTemplate transactionTemplate; 
  3.     
  4.    ... 
  5.     
  6.    public void save(final User user) { 
  7.          transactionTemplate.execute((status) => { 
  8.             addData();            
  9.             return Boolean.TRUE
  10.          }) 
  11.          addLog(); 
  12.          updateCount(); 
  13.    } 

當然大事務中要鑒別出哪些方法可以非事務執行,其實沒那么容易,需要對整個業務梳理一遍,才能找出最合理的答案。

異步處理

還有一點也非常重要,是不是事務中的所有方法都需要同步執行?我們都知道,方法同步執行需要等待方法返回,如果一個事務中同步執行的方法太多了,勢必會造成等待時間過長,出現大事務問題。

看看下面這個列子:

  1. @Autowired 
  2.    private TransactionTemplate transactionTemplate; 
  3.     
  4.    ... 
  5.     
  6.    public void save(final User user) { 
  7.          transactionTemplate.execute((status) => { 
  8.             order(); 
  9.             delivery(); 
  10.             return Boolean.TRUE
  11.          }) 
  12.    } 

order方法用于下單,delivery方法用于發貨,是不是下單后就一定要馬上發貨呢?

答案是否定的。

這里發貨功能其實可以走mq異步處理邏輯。

  1. @Autowired 
  2.    private TransactionTemplate transactionTemplate; 
  3.     
  4.    ... 
  5.     
  6.    public void save(final User user) { 
  7.          transactionTemplate.execute((status) => { 
  8.             order(); 
  9.             return Boolean.TRUE
  10.          }) 
  11.          sendMq(); 
  12.    } 

總結

本人從網友的一個問題出發,結合自己實際的工作經驗分享了處理大事務的6種辦法:

  • 少用@Transactional注解
  • 將查詢(select)方法放到事務外
  • 事務中避免遠程調用
  • 事務中避免一次性處理太多數據
  • 非事務執行
  • 異步處理
責任編輯:武曉燕 來源: 蘇三說技術
相關推薦

2012-02-14 09:59:09

NoSQLCouchDB

2023-11-28 08:00:00

SpringJava

2017-12-14 10:35:54

iOSAPPiPhone

2012-09-05 11:09:15

SELinux操作系統

2024-01-10 09:44:11

MySQL死鎖

2017-10-17 09:21:06

2010-04-29 17:46:31

Oracle死鎖

2019-11-26 14:30:20

Spring循環依賴Java

2023-07-18 16:05:00

IP地址

2024-12-05 09:06:58

2021-10-20 20:27:55

MySQL死鎖并發

2009-09-21 17:10:14

struts Hibe

2024-01-15 07:05:50

開發大事務數據庫

2014-04-10 13:55:24

2019-05-27 09:00:00

蘇寧智慧零售平臺數據庫

2010-07-16 13:52:26

telnet漏洞

2023-10-30 18:35:47

MySQL主從延時

2011-03-23 14:42:47

CPU過度消耗

2021-06-06 13:05:15

前端跨域CORS

2011-08-29 10:34:00

網絡安全云安全云計算
點贊
收藏

51CTO技術棧公眾號

激情成人中文字幕| 国产综合色视频| 亚洲人成亚洲人成在线观看| 97国产在线播放| 桃花色综合影院| 亚洲女同同性videoxma| 亚洲老司机av| 伊人成人222| 欧美1234区| 2023国产精品| 国产精品一区二区久久久| 青青草华人在线视频| 成人四虎影院| 一区二区三区视频在线看| 国产综合 伊人色| 国产一区二区视频免费| 婷婷综合激情| 亚洲激情在线观看| 无码人妻h动漫| 里番在线观看网站| 国产精品一区二区在线观看不卡| 中文字幕欧美日韩精品| 亚洲综合激情视频| 精品久久久久久无码中文野结衣| 中文字幕久久久久| 欧美日本一区二区高清播放视频| 亚洲黄色成人网| 妺妺窝人体色www在线观看| 美女免费久久| 久久亚洲精精品中文字幕早川悠里 | 91日韩在线专区| 欧美做受高潮电影o| 永久免费看片直接| 国产va免费精品观看精品视频| 在线播放视频一区| avav在线看| 日本伦理一区二区| 国产亚洲精品7777| 国产精品 日韩| 久久久久久av无码免费看大片| 欧美激情视频一区二区三区在线播放| 精品视频中文字幕| 国产无遮挡猛进猛出免费软件| av在线不卡免费| 成人免费小视频| 欧美视频观看一区| 亚洲欧美另类一区| 国内精品国产三级国产a久久| 秋霞成人午夜鲁丝一区二区三区| 久久黄色免费网站| 99热国内精品永久免费观看| 亚洲视频日韩精品| 国模私拍在线观看| 亚洲精品a区| 3d动漫精品啪啪| 日本美女高潮视频| 伊人久久综合一区二区| 婷婷成人综合网| 久久亚洲a v| www视频在线看| 国产精品美女一区二区三区| 欧洲精品亚洲精品| 欧美一区二区少妇| 久久这里只有精品首页| 亚洲精品视频免费观看| 亚洲自拍偷拍色图| 一本一道精品欧美中文字幕| 久久天堂成人| 91极品女神在线| 日本亚洲欧美在线| 亚洲国产第一| 高清视频欧美一级| 中日韩精品视频在线观看| 在线精品福利| 欧美国产激情18| 欧美日韩一级在线观看| 91精品成人| 久久成人国产精品| 久久高清内射无套| 中文字幕一区二区三区乱码图片| 久久影院模特热| 69av视频在线| 一区在线播放| 欧美猛交免费看| 黄色一级片在线| 韩日成人在线| 668精品在线视频| 国产一级免费视频| 久久久精品日韩| 国产精品成久久久久三级| 国产天堂第一区| 久久丁香综合五月国产三级网站| 国产精品男人爽免费视频1| 亚洲图片中文字幕| 婷婷在线免费视频| 99精品国产热久久91蜜凸| 精品视频第一区| 国产精品秘入口| 中文字幕一区二区三区在线不卡| 日本黄xxxxxxxxx100| 国产乱色在线观看| 午夜婷婷国产麻豆精品| 精品免费国产一区二区| 97精品资源在线观看| 亚洲第一av在线| 中文字幕xxx| 99久久激情| 国内精品久久久久伊人av| 黄色一级视频免费看| 久久精品国产免费看久久精品| 一区二区三区加勒比av| 精品不卡在线| 99精品老司机免费视频| 一区2区3区在线看| 欧美网站免费观看| 亚洲男女网站| 亚洲激情在线视频| 国产精品国产三级国产传播| 99国内精品| 成人在线视频福利| 午夜福利视频一区二区| √…a在线天堂一区| 久久国产午夜精品理论片最新版本| 在线天堂资源| 日韩欧美在线123| 第一次破处视频| 欧美视频久久| 欧美夜福利tv在线| 国产深喉视频一区二区| 久久久噜噜噜久久人人看| www.亚洲一区二区| 欧美男女交配| 亚洲第一天堂av| 免费高清在线观看电视| 久久一区亚洲| 国产精品日韩欧美一区二区| 青青草免费在线视频| 一区二区三区中文字幕精品精品| 成年人在线看片| 加勒比色老久久爱综合网| 亚洲一级黄色片| 日韩三级小视频| 国产寡妇亲子伦一区二区| 亚洲日本精品| 电影一区二区三| 亚洲国产高清高潮精品美女| 久久国产精品国语对白| 久久av中文字幕片| 日本欧洲国产一区二区| 欧美aa一级| 日韩精品一区二区三区四区视频| 久久视频一区二区三区| 亚洲视频成人| 国产精品二区三区四区| av免费在线免费| 欧美福利视频导航| 欧美激情久久久久久久| 久久裸体视频| 欧美日韩大片一区二区三区| 中文在线最新版地址| 米奇精品一区二区三区| 欧美小视频在线| 在线免费看黄色片| 亚洲视频一区| 91精品国产91久久久久青草| av黄在线观看| 日韩一区二区三区精品视频| www.毛片com| 国产精品乡下勾搭老头1| 只有这里有精品| 亚洲影视资源| 久久中文字幕视频| 国产毛片久久久久| 亚洲欧美日韩电影| 亚洲精品在线网址| 三区四区不卡| 91视频免费网站| 2024短剧网剧在线观看| 精品国产免费一区二区三区香蕉| www.av成人| 国产激情一区二区三区四区| 在线观看成人av电影| 不卡精品视频| 欧美疯狂做受xxxx高潮| 亚洲第一天堂影院| 欧美日韩亚洲国产一区| 色欲AV无码精品一区二区久久| 日本不卡一二三区黄网| 一区二区三区在线视频111 | 欧美尤物巨大精品爽| 嫩草精品影院| 精品视频一区三区九区| 国产视频123区| 国产suv一区二区三区88区| 国产成人一区二区三区别| 亚洲大片精品免费| 国产日韩av在线| 日本h片在线| 亚洲欧美制服另类日韩| 一级片一区二区三区| 亚洲高清不卡在线观看| 色无极影院亚洲| 久久99精品久久久久婷婷| 成人小视频在线观看免费| 精品中文一区| 亚洲综合中文字幕在线| 97天天综合网| 最新的欧美黄色| 国产免费一区二区三区最新不卡| 亚洲国产成人va在线观看天堂| 少妇特黄一区二区三区| 蜜芽一区二区三区| 亚洲国产精品成人天堂| 欧美三级美国一级| 成人动漫在线视频| 99久久精品一区二区成人| 久久91亚洲精品中文字幕| 青青青草网站免费视频在线观看| 777xxx欧美| 日本中文字幕第一页| 一区二区三区日韩欧美精品| 免费黄色三级网站| 韩国欧美一区二区| 成人观看免费完整观看| 久久人体视频| 久久伦理网站| 一级毛片精品毛片| 国产精品爽爽ⅴa在线观看| 国产极品人妖在线观看| 色yeye香蕉凹凸一区二区av| 999免费视频| 欧美色图12p| 日韩精品在线免费视频| 亚洲精品第1页| 成人无码精品1区2区3区免费看| 波波电影院一区二区三区| 五月婷婷狠狠操| 在线亚洲观看| 日韩一级性生活片| 91精品久久久久久久久久不卡| 日本a级片久久久| 欧美久久香蕉| 国产精品乱码视频| 欧洲大片精品免费永久看nba| 国产精品久久久久9999| 中文字幕在线中文字幕在线中三区| 免费av在线一区| 人人干在线视频| 日韩在线免费av| 美女隐私在线观看| 欧美成人手机在线| 亚洲综合影视| 欧美激情乱人伦一区| av资源网在线播放| 欧美在线免费视频| 久久久久久久| 国产精品久久久久久搜索| 97久久网站| 91在线观看免费网站| 亚洲一级大片| 国产一区二区黄色| 亚洲精品进入| 欧美一区二视频在线免费观看| 欧洲乱码伦视频免费| 综合网五月天| 你懂的国产精品永久在线| av在线com| 另类亚洲自拍| 另类小说色综合| 国产精一区二区三区| 捆绑凌虐一区二区三区| 久久久国产一区二区三区四区小说| 午夜时刻免费入口| 中文字幕一区二区三区在线播放 | 在线观看一区二区三区四区| av在线不卡免费看| 国产视频三区四区| 伊人色综合久久天天人手人婷| 亚洲国产综合久久| 在线影院国内精品| 精品国产18久久久久久| 日韩毛片在线观看| 日本在线观看免费| 久久久久国产精品一区| 成人激情综合| 7777精品伊久久久大香线蕉语言| 欧美人妖在线观看| 亚洲午夜在线观看| 一级成人国产| 欧美午夜精品理论片| 99久久精品国产一区| 久久精品色妇熟妇丰满人妻| 亚洲一区二区视频在线观看| 日韩免费av网站| 日韩精品一区二区三区视频| 蜜桃免费在线| 欧美巨乳在线观看| 欧美va视频| 国产精品一区二区欧美| 久久国产亚洲| aa在线免费观看| 国产在线播放一区三区四| 久久精品老司机| 亚洲人xxxx| www.久久网| 亚洲精品第一国产综合精品| 国产人成网在线播放va免费| 日韩av电影手机在线| a看欧美黄色女同性恋| 亚洲不卡一卡2卡三卡4卡5卡精品| 午夜精品av| 最新中文字幕2018| 久久综合久久99| 国产一级生活片| 91.麻豆视频| 91在线视频| 日本精品一区二区三区在线播放视频| 精品一区二区三区在线观看视频 | 精品国产人妻一区二区三区| 亚洲欧洲国产日韩| 99久久久无码国产精品免费蜜柚| 精品国产1区二区| 伦xxxx在线| 国产精品久久久久久久久久99| 亲子伦视频一区二区三区| 日本高清视频免费在线观看| 久久99热99| 美国美女黄色片| 色婷婷综合久久| 五月婷婷激情在线| 久久久综合免费视频| 日本一区二区乱| 免费的av在线| 国产在线播放一区| 欧美日韩午夜视频| 91精品国产综合久久婷婷香蕉| h视频网站在线观看| 青草青草久热精品视频在线网站 | 中文国产成人精品| 美女写真久久影院| 任我爽在线视频精品一| 久久综合九色| 亚洲综合网在线观看| 欧美日韩国产专区| 香港三日本三级少妇66| 7m精品福利视频导航| 欧美三级午夜理伦三级在线观看| 日韩五码在线观看| 成人激情av网| 三级黄色在线视频| 亚洲精品一区二区网址| 中文字幕乱码在线播放| 日韩久久久久久久| 免费成人av在线| 99鲁鲁精品一区二区三区| 欧美一区二区视频在线观看2020 | 亚洲国产日韩在线一区| 亚洲女人****多毛耸耸8| 国产手机av在线| 欧美国产第一页| 欧美一区二区三区红桃小说| 91免费视频网站在线观看| 国产亚洲精品7777| 国产一区二区自拍视频| 欧美老少配视频| 牲欧美videos精品| 欧美xxxxx在线视频| 日本一区二区综合亚洲| 国产乱码精品一区二区三区精东| 久热99视频在线观看| 久久久久久毛片免费看 | 久久一二三四区| 日韩经典中文字幕| 姬川优奈av一区二区在线电影| 亚洲欧洲日本国产| 国产福利一区二区三区| 在线观看免费国产视频| 亚洲欧美日韩国产中文| 日韩成人精品一区二区三区| 18视频在线观看娇喘| 波多野结衣中文字幕一区| 少妇无套内谢久久久久| 成人444kkkk在线观看| 欧美人妖在线观看| 性生生活大片免费看视频| 亚洲在线观看免费| 国产三级视频在线播放线观看| 91免费观看网站| 国产欧美在线| 永久免费看片视频教学| 日韩美女一区二区三区四区| 国产免费不卡| 性做爰过程免费播放| 91久色porny| 99久久久国产精品无码免费| 日本不卡免费高清视频| 欧美视频不卡| 永久免费观看片现看| 日韩电影在线观看中文字幕| 免费成人黄色网|