佳木斯湛栽影视文化发展公司

主頁 > 知識(shí)庫 > MySQL嵌套事務(wù)所遇到的問題

MySQL嵌套事務(wù)所遇到的問題

熱門標(biāo)簽:鐵路電話系統(tǒng) 百度競價(jià)排名 服務(wù)外包 呼叫中心市場需求 Linux服務(wù)器 網(wǎng)站排名優(yōu)化 AI電銷 地方門戶網(wǎng)站

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

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

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ù)的失敗會(huì)回滾的。  但事實(shí)不是這樣的,最后的結(jié)果是  1 2 3 .

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

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

begin_1  sql_1  begin_2  sql_2  sql_3 commit_1  rollback_1  .

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

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

那么怎么規(guī)避這風(fēng)險(xiǎn) ?  可以加鎖呀….   設(shè)立一個(gè)全局鎖,當(dāng)子事務(wù)創(chuàng)建前會(huì)判斷鎖的狀態(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í)行下面語句的時(shí)候,事務(wù)會(huì)被強(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  

您可能感興趣的文章:
  • PHP中實(shí)現(xiàn)MySQL嵌套事務(wù)的兩種解決方案
  • MySQL存儲(chǔ)過程例子(包含事務(wù),輸出參數(shù),嵌套調(diào)用)

標(biāo)簽:銅川 衡水 黃山 崇左 仙桃 蘭州 湘潭 湖南

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《MySQL嵌套事務(wù)所遇到的問題》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266
    思南县| 抚宁县| 青川县| 砀山县| 历史| 广南县| 都昌县| 宜良县| 读书| 长宁县| 威海市| 普格县| 无为县| 仙桃市| 嘉定区| 广宁县| 交城县| 成武县| 霍山县| 和林格尔县| 平邑县| 安庆市| 顺平县| 博客| 祁阳县| 定安县| 朝阳区| 南漳县| 库车县| 桐庐县| 眉山市| 交口县| 高州市| 南京市| 南城县| 响水县| 当雄县| 元朗区| 蒲江县| 乳山市| 久治县|