MySQL嵌套事務(wù)所遇到的問題的代碼實(shí)例詳解

這篇文章主要介紹了mysql嵌套事務(wù)所遇到的問題的相關(guān)資料,需要的朋友可以參考下

MySQL是支持嵌套事務(wù)的,但是沒多少人會這么干的…. 前段時間在國外看到一些老外在爭論MySQL嵌套事務(wù)的場景必要性。 逗死我了, 這嵌套的鬼畜用法還有啥場景必要性。?? 跟以前的dba同事聊過, 得知,在任何場景下都不要使用MySQL嵌套的事務(wù)。

那么使用MySQL嵌套事務(wù)會遇到什么問題 ?

mysql>?select?*?from?ceshi;?  +------+?  |?n??|?  +------+?  |??1?|?  +------+?  1?row?in?set?(0.00?sec)?  ?  mysql>?start?transaction?;?  Query?OK,?0?rows?affected?(0.00?sec)?  ?  mysql>?insert?into?ceshi?values(2);?  Query?OK,?1?row?affected?(0.00?sec)?  ?  mysql>?start?transaction?;?  Query?OK,?0?rows?affected?(0.00?sec)?  ?  mysql>?insert?into?ceshi?values(3);?  Query?OK,?1?row?affected?(0.00?sec)?  ?  mysql>?commit;?  Query?OK,?0?rows?affected?(0.00?sec)?  ?  mysql>?rollback;?  Query?OK,?0?rows?affected?(0.00?sec)

雖然我在最后rollback回滾了,但是數(shù)據(jù)顯示是? 1 2 3? .??? 原本大家以為我的事務(wù)雖然是嵌套的狀態(tài),但感覺最后rollback回滾了,其實(shí)我們希望看到的結(jié)果是 子事務(wù)執(zhí)行成功,外層事務(wù)的失敗會回滾的。? 但事實(shí)不是這樣的,最后的結(jié)果是? 1 2 3 .

+-----+?  |?n???|?  +-----+?  |??1?|?  |??2?|?  |??3?|?  +-----+

當(dāng)sql解釋器遇到 start transaction 時候會觸發(fā)commit… !!!???

begin_1? sql_1? begin_2? sql_2? sql_3 commit_1? rollback_1? .

begin_2 被執(zhí)行的時候, sql_1 已經(jīng)就被提交了, 當(dāng)你再去執(zhí)行commit_1的時候,那么sql_2 和 sql_3 就被提交了.??? 這時候你再去rollback,一定用都沒有….??? 因?yàn)橄惹岸继峤煌炅?,你能回滾啥…

前面說過 在架構(gòu)上一般很少很少有人會 嵌套使用事務(wù),但有時候不小心被嵌套了。 我們拿python的項(xiàng)目來說,首先我們使用裝飾器來實(shí)現(xiàn)事務(wù)的包裝, 接著數(shù)據(jù)處理 def a() 和? def b() 函數(shù)都被事務(wù)被包裝起來, 單純的用a 和 b 都沒關(guān)系,都是單事務(wù)。? 如果 a 邏輯里又調(diào)用 b, 那么會發(fā)生什么??? 對的,事務(wù)嵌套了…??? 我想這是絕大數(shù)業(yè)務(wù)開發(fā)都會遇到的問題。

那么怎么規(guī)避這風(fēng)險 ?? 可以加鎖呀….?? 設(shè)立一個全局鎖,當(dāng)子事務(wù)創(chuàng)建前會判斷鎖的狀態(tài)….

如果你是flask的框架,可以使用 flask g 全局變量。??

如果是django框架, 那么可以使用 thread local使用全局變量。

如果是tornado、gevent這種異步io架構(gòu),可以使用 fd 做協(xié)程變量的關(guān)聯(lián)。

@decorator  def?with_transaction(f,?*args,?**kwargs):  ?  ??db?=?connection.get_db_by_table("*")  ??try:  ????db.begin()  ????ret?=?f(*args,?**kwargs)  ????db.commit()  ??except:  ????db.rollback()  ????raise  ??return?ret  ?  ?  @with_transaction  def?hide(self):  ??'''訂單不在app端顯示'''  ??if?self.status?not?in?OrderStatus.allow_deletion_statuses():  ????raise?OrderStatusChangeNotAllowed(self.status,?OrderStatus.deleted)  ...  ?  ?  @with_transaction  def?change_receipt_info(self,?address,?name,?phone):  ??region?=?Region.get_by_address(address)  ??...

當(dāng)我們?nèi)?zhí)行下面語句的時候,事務(wù)會被強(qiáng)制提交.?? 當(dāng)然這里前提是 autocommit = True 。

ALTER?FUNCTION??  ALTER?PROCEDURE??  ALTER?TABLE??  BEGIN??  CREATE?DATABASE??  CREATE?FUNCTION??  CREATE?INDEX??  CREATE?PROCEDURE??  CREATE?TABLE??  DROP?DATABASE??  DROP?FUNCTION??  DROP?INDEX??  DROP?PROCEDURE??  DROP?TABLE??  UNLOCK?TABLES??  LOAD?MASTER?DATA??  LOCK?TABLES??  RENAME?TABLE??  TRUNCATE?TABLE??  SET?AUTOCOMMIT=1??  START?TRANSACTION

以上就是MySQL嵌套事務(wù)所遇到的問題的代碼實(shí)例詳解的內(nèi)容,更多相關(guān)內(nèi)容請關(guān)注PHP中文網(wǎng)(www.php.cn)!

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊12 分享