這篇文章主要介紹了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)!