SQL第20課:管理事務(wù)處理

事務(wù)定義:
事務(wù)是單個的工作單元蝇恶。如果某一事務(wù)成功拳魁,則在該事務(wù)中進行的所有數(shù)據(jù)更改均會提交,成為數(shù)據(jù)庫中的永久組成部分撮弧。如果事務(wù)遇到錯誤且必須取消或回滾潘懊,則所有數(shù)據(jù)更改均被清除姚糊。一般來說,事務(wù)是必須滿足4個條件(ACID)::原子性(Atomicity授舟,或稱不可分割性)救恨、一致性(Consistency)、隔離性(Isolation释树,又稱獨立性)忿薇、持久性(Durability)。

  • 事務(wù)(transaction)一組SQL指令
  • 回退(rollback)撤銷指定SQL語句的過程
  • 提交(commit)將未存儲的SQL語句結(jié)果寫入數(shù)據(jù)庫表
  • 保留點(savepoint)事務(wù)中設(shè)置的臨時占位符(placeholder)躏哩,可以對他發(fā)布回退(與回退整個事務(wù)不同)

在用戶操作MySQL過程中署浩,對于一般簡單的業(yè)務(wù)邏輯或中小型程序而言,無需考慮應(yīng)用MySQL事務(wù)扫尺。但在比較復雜的情況下筋栋,往往用戶在執(zhí)行某些數(shù)據(jù)操作過程中,需要通過一組SQL語句執(zhí)行多項并行業(yè)務(wù)邏輯或程序正驻,這樣弊攘,就必須保證所用命令執(zhí)行的同步性。使執(zhí)行序列中姑曙,產(chǎn)生依靠關(guān)系的動作能夠同時操作成功或同時返回初始狀態(tài)襟交。在此情況下,就需要用戶優(yōu)先考慮使用MySQL事務(wù)處理伤靠。

在MySQL中捣域,事務(wù)由單獨單元的一個或多個SQL語句組成。在這個單元中宴合,每個MySQL語句是相互依賴的焕梅。而整個單獨單元作為一個不可分割的整體,如果單元中某條SQL語句一旦執(zhí)行失敗或產(chǎn)生錯誤卦洽,整個單元將會回滾贞言。所有受到影響的數(shù)據(jù)將返回到事務(wù)開始以前的狀態(tài);如果單元中的所有SQL語句均執(zhí)行成功阀蒂,則事務(wù)被順利執(zhí)行该窗。

通過InnoDB和BDB類型表,MySQL事務(wù)能夠完全滿足事務(wù)安全的ACID測試蚤霞,但是并不是所有表類型都支持事務(wù)酗失,如MyISAM類型表就不能支持事務(wù),只能通過偽事務(wù)對表實現(xiàn)事務(wù)處理争便。

MySQL事務(wù)的創(chuàng)建與存在周期

創(chuàng)建事務(wù)

創(chuàng)建事務(wù)的一般過程是:初始化事務(wù)级零、創(chuàng)建事務(wù)、應(yīng)用SELECT語句查詢數(shù)據(jù)是否被錄入和提交事務(wù)。如果用戶不在操作數(shù)據(jù)庫完成后執(zhí)行事務(wù)提交奏纪,則系統(tǒng)會默認執(zhí)行回滾操作鉴嗤。如果用戶在提交事務(wù)前選擇撤銷事務(wù),則用戶在撤銷前的所有事務(wù)將被取消序调,數(shù)據(jù)庫系統(tǒng)會回到初始狀態(tài)醉锅。

默認情況下,在MySQL中創(chuàng)建的數(shù)據(jù)表類型都是MyISAM发绢,但是該類型的數(shù)據(jù)表并不能支持事務(wù)硬耍。所以,如果用戶想讓數(shù)據(jù)表支持事務(wù)處理能力边酒,必須將當前操作數(shù)據(jù)表的類型設(shè)置為InnoDB或BDB经柴。

在創(chuàng)建事務(wù)的過程中,用戶需要創(chuàng)建一個InnoDB或BDB類型的數(shù)據(jù)表墩朦,其基本命令結(jié)構(gòu)如下:

CREATE TABLE table_name(field-defintions)TYPE=INNODB/BDB坯认;

其中,table_name為表名氓涣,而field_defintions為表內(nèi)定義的字段等屬性牛哺,TYPE為數(shù)據(jù)表的類型,既可以是InnoDB類型劳吠,同樣也可以是BDB類型引润。

當用戶希望已經(jīng)存在的表支持事務(wù)處理,則可以應(yīng)用ALTER TABLE命令指定數(shù)據(jù)表的類型實現(xiàn)對表的類型更改操作痒玩,使原本不支持事務(wù)的數(shù)據(jù)表更改為支持事務(wù)處理的類型淳附。其命令如下:

ALTER TABLE table_name TYPE=INNODB/BDB;

當用戶更改完表的類型后凰荚,即可使數(shù)據(jù)表支持事務(wù)處理燃观。

應(yīng)用ALTER TABLE操作可能會導致數(shù)據(jù)庫中數(shù)據(jù)丟失褒脯,因此為了避免非預(yù)期結(jié)果出現(xiàn)便瑟,在使用ALTER TABLE命令之前,用戶需要創(chuàng)建一個表備份番川。

初始化事務(wù)

初始化MySQL事務(wù)到涂,首先聲明初始化MySQL事務(wù)后所有的SQL語句為一個單元。在MySQL中颁督,應(yīng)用START TRANSACTION命令來標記一個事務(wù)的開始践啄。初始化事務(wù)的結(jié)構(gòu)如下:

START TRANSACTION;

另外沉御,用戶也可以使用BEGIN或者BEGIN WORK命令初始化事務(wù)屿讽,通常START TRANSACTION命令后面跟隨的是組成事務(wù)的SQL語句。

在命令提示符中輸入如下命令:

start transaction;

如果在用戶輸入以上代碼后伐谈,MySQL數(shù)據(jù)庫沒有給出警告提示或返回錯誤信息烂完,則說明事務(wù)初始化成功,用戶可以繼續(xù)執(zhí)行下一步操作诵棵。

創(chuàng)建事務(wù)

insert into connection(email, cellphone, QQ, sid)

values('barrystephen@126.com'抠蚣,13456000000,187034000履澳,3)嘶窄;

應(yīng)用SELECT語句查看數(shù)據(jù)是否被正確輸入

SELECT * FROM connection WHERE sid=3;

ps:在用戶插入新表為“InnoDB”類型或更改原來表類型為“InnoDB”時距贷,如果在輸入命令提示后柄冲,MySQL提示“The 'InnoDB' feature is disabled;you needInnoDB' to have it working”警告忠蝗,則說明InnoDB表類型并沒有被開啟羊初,用戶需要找到MySQL文件目錄下的“my.ini”文件,定位“skip_innodb”選項位置什湘,將原來的“skip_innodb”改為“#skip_innodb”后保存該文件长赞,重新啟動MySQL服務(wù)器,即可令數(shù)據(jù)庫支持“InnoDB”類型表闽撤。

提交事務(wù)

在用戶沒有提交事務(wù)之前得哆,當其他用戶連接MySQL服務(wù)器時,應(yīng)用SELECT語句查詢結(jié)果哟旗,則不會顯示沒有提交的事務(wù)贩据。當且僅當用戶成功提交事務(wù)后,其他用戶才可能通過SELECT語句查詢事務(wù)結(jié)果闸餐,由事務(wù)的特性可知饱亮,事務(wù)具有孤立性,當事務(wù)處在處理過程中舍沙,其實MySQL并未將結(jié)果寫入磁盤中近上,這樣一來,這些正在處理的事務(wù)相對其他用戶是不可見的拂铡。一旦數(shù)據(jù)被正確插入壹无,用戶可以使用COMMIT命令提交事務(wù)。提交事務(wù)的命令結(jié)構(gòu)如下:

COMMIT

一旦當前執(zhí)行事務(wù)的用戶提交當前事務(wù)感帅,則其他用戶就可以通過會話查詢結(jié)果斗锭。

撤銷事務(wù)(事務(wù)回滾)

撤銷事務(wù),又被稱作事務(wù)回滾失球。即事務(wù)被用戶開啟岖是、用戶輸入的SQL語句被執(zhí)行后,如果用戶想要撤銷剛才的數(shù)據(jù)庫操作,可使用ROLLBACK命令撤銷數(shù)據(jù)庫中的所有變化豺撑。ROLLBACK命令結(jié)構(gòu)如下:

ROLLBACK

輸入回滾操作后作箍,如何判斷是否執(zhí)行回滾操作了呢?可以通過SELECT語句查看11.2.2小節(jié)中插入的數(shù)據(jù)是否存在.

如果執(zhí)行一個回滾操作前硫,則在輸入START TRANSACTIONA命令后的所有SQL語句都將執(zhí)行回滾操作胞得。故在執(zhí)行事務(wù)回滾前,用戶需要慎重選擇執(zhí)行回滾操作屹电。如果用戶開啟事務(wù)后阶剑,沒有提交事務(wù),則事務(wù)默認為自動回滾狀態(tài)危号,即不保存用戶之前的任何操作牧愁。

事務(wù)的存在周期

事務(wù)的周期由用戶在命令提示符中輸入START TRANSACTION指令開始,直至用戶輸入COMMIT結(jié)束.

事務(wù)不支持嵌套功能外莲,當用戶在未結(jié)束第一個事務(wù)又重新打開一個事務(wù)猪半,則前一個事務(wù)會自動提交,同樣MySQL命令中很多命令都會隱藏執(zhí)行COMMIT命令偷线。

MySQL行為

在MySQL中磨确,存在兩個可以控制行為的變量,它們分別是AUTOCOMMIT變量和TRANSACTION ISOLACTION LEVEL變量声邦。

自動提交

在MySQL中乏奥,如果不更改其自動提交變量,則系統(tǒng)會自動向數(shù)據(jù)庫提交結(jié)果亥曹,用戶在執(zhí)行數(shù)據(jù)庫操作過程中邓了,不需要使用START TRANSACTION語句開始事務(wù),應(yīng)用COMMIT或者ROLLBACK提交事務(wù)或執(zhí)行回滾操作媳瞪。如果用戶希望通過控制MySQL自動提交參數(shù)骗炉,可以更改提交模式,這一更改過程是通過設(shè)置AUTOCOMMIT變量來實現(xiàn)蛇受。

下面通過一個示例向讀者展示如何關(guān)閉自動提交參數(shù)句葵。在命令提示符中輸入以下命令:

SET AUTOCOMMIT=0;

只有當用戶輸入COMMIT命令后龙巨,MySQL才將數(shù)據(jù)表中的資料提交到數(shù)據(jù)庫中笼呆,如果不提交事務(wù),而終止MySQL會話旨别,數(shù)據(jù)庫將會自動執(zhí)行回滾操作。

可以通過查看“@@AUTOCOMMIT”變量來查看當前自動提交狀態(tài)汗茄,查看此變量SELECT @@AUTOCOMMIT秸弛。

事務(wù)的隔離級別

基于ANSI/ISO SQL規(guī)范,MySQL提供4種孤立級:

SERIALIZABLE(序列化)

REPEATABLE READ(可重讀)

READ COMMITTED(提交后讀)

READ UNCOMMITTED(未提交讀)

在MySQL中,可以使用TRANSACTION ISOLATION LEVEL變量來修改事務(wù)孤立級递览,其中叼屠,MySQL的默認隔離級別為REPEATABLE READ(可重讀),用戶可以使用SELECT命令獲取當前事務(wù)孤立級變量的值绞铃,其命令如下:

SELECT @@tx_isolation镜雨;

如果用戶想要修改事務(wù)的隔離級別,必須首先獲取SUPER優(yōu)先權(quán)儿捧,以便用戶可以順利執(zhí)行修改操作荚坞,set。

事務(wù)的使用技巧和注意事項

應(yīng)用小事務(wù)菲盾,保證每個事務(wù)不會在執(zhí)行前等待很長時間颓影,從而避免各個事務(wù)因為互相等待而導致系統(tǒng)性能的大幅度下降。

選擇合適的孤立級懒鉴,因為事務(wù)的性能與其對服務(wù)器產(chǎn)生的負載成反比诡挂,即當事務(wù)孤立級越高,其性能越低临谱,但是其安全性也越高璃俗。只有選擇適當?shù)墓铝⒓墸拍苡行У靥岣進ySQL系統(tǒng)性能和應(yīng)用性悉默。

死鎖的概念與避免旧找,即當兩個或者多個處于不同序列的用戶打算同時更新某相同的數(shù)據(jù)庫時,因互相等待對方釋放權(quán)限而導致雙方一直處于等待狀態(tài)麦牺。在實際應(yīng)用中钮蛛,兩個不同序列的客戶打算同時對數(shù)據(jù)執(zhí)行操作,極有可能產(chǎn)生死鎖剖膳。更具體地講魏颓,當兩個事務(wù)相互等待操作對方釋放所持有的資源,而導致兩個事務(wù)都無法操作對方持有的資源吱晒,這樣無限期的等待被稱作死鎖甸饱。MySQL的InnoDB表處理程序具有檢查死鎖這一功能,如果該處理程序發(fā)現(xiàn)用戶在操作過程中產(chǎn)生死鎖仑濒,該處理程序立刻通過撤銷操作來撤銷其中一個事務(wù)叹话,以便使死鎖消失。這樣就可以使另一個事務(wù)獲取對方所占有的資源而執(zhí)行邏輯操作墩瞳。

MySQL偽事務(wù)

在MySQL中驼壶,InnoDB和BDB類型表可以支持事務(wù)處理,但是MySQL中MyISAM類型表并不能支持事務(wù)處理喉酌,對于某些應(yīng)用該類型的數(shù)據(jù)表热凹,用戶可以選擇應(yīng)用表鎖定來替代事務(wù)柿祈。這種引用表鎖定來替代事務(wù)的事件被稱作偽事務(wù)羞酗。使用表鎖定來鎖定表的操作,可以加強非事務(wù)表在執(zhí)行過程的安全性和穩(wěn)定性。

用表鎖定代替事務(wù)

在MySQL的MyISAM類型數(shù)據(jù)表中戈鲁,并不支持COMMIT(提交)和ROLLBACK(回滾)命令坦胶。當用戶對數(shù)據(jù)庫執(zhí)行插入叔扼、刪除街氢、更新等操作時,這些變化的數(shù)據(jù)都被立刻保存在磁盤中苫拍。這樣芜繁,在多用戶環(huán)境中,會導致諸多問題怯疤。為了避免同一時間有多個用戶對數(shù)據(jù)庫中指定表進行操作浆洗,可以應(yīng)用表鎖定來避免在用戶操作數(shù)據(jù)表過程中受到干擾。當且僅當該用戶釋放表的操作鎖定后集峦,其他用戶才可以訪問這些修改后的數(shù)據(jù)表伏社。

設(shè)置表鎖定代替事務(wù)基本步驟如下:

(1)為指定數(shù)據(jù)表添加鎖定。其語法如下:

LOCK TABLES table_name lock_type塔淤,……

其中摘昌,table_name為被鎖定的表名,lock_type為鎖定類型高蜂,該類型包括以讀方式(READ)鎖定表聪黎,以寫方式(WRITE)鎖定表。

(2)用戶執(zhí)行數(shù)據(jù)表的操作备恤,可以添加稿饰、刪除或者更改部分數(shù)據(jù)。

(3)用戶完成對鎖定數(shù)據(jù)表的操作后露泊,需要對該表進行解鎖操作喉镰,釋放該表的鎖定狀態(tài)。其語法如下:

UNLOCK TABLES

以讀方式鎖定數(shù)據(jù)表惭笑,該方式是設(shè)置鎖定用戶的其他方式操作侣姆,如刪除、插入沉噩、更新都不被允許捺宗,直至用戶進行解鎖操作。

lock table studentinfo read川蒙;

其中的lock_type參數(shù)中蚜厉,用戶指定數(shù)據(jù)表以讀方式(READ)鎖定數(shù)據(jù)表的變體為READ LOCAL鎖定,其與READ鎖定的不同點是派歌,該參數(shù)所指定的用戶會話可以執(zhí)行INSERT操作弯囊,它是為了使用MySQL dump工具而創(chuàng)建的一種變體形式痰哨。

以寫方式鎖定數(shù)據(jù)表胶果,該方式是是設(shè)置用戶可以修改數(shù)據(jù)表中的數(shù)據(jù)匾嘱,但是除自己以外其他會話中的用戶不能進行任何讀操作。在命令提示符中輸入如下命令:

lock table studentinfo write早抠;

當數(shù)據(jù)表被釋放鎖定后霎烙,其他訪問數(shù)據(jù)庫的用戶即可查看數(shù)據(jù)表的內(nèi)容。

應(yīng)用表鎖實現(xiàn)偽事務(wù)

通過使用表鎖定對MyISAM表進行鎖定操作蕊连,以此過程來代替事務(wù)型表InnoDB悬垃,即應(yīng)用表鎖定來實現(xiàn)偽事務(wù)。實現(xiàn)偽事務(wù)的一般步驟如下:

(1)對數(shù)據(jù)庫中的數(shù)據(jù)表進行鎖定操作甘苍,可以對多個表做不同的方式鎖定尝蠕,其代碼格式如下:

LOCK TABLE table_name1 lock_type1,table_name2 lock_type2载庭,……

(2)執(zhí)行數(shù)據(jù)庫操作看彼,向鎖定的數(shù)據(jù)表中執(zhí)行添加、刪除囚聚、修改操等操作靖榕。

如前面提到的INSERT、UPDATE顽铸、DELETE等操作茁计。用戶可以對鎖定的數(shù)據(jù)表執(zhí)行上述操作,在執(zhí)行過程中谓松,該偽事務(wù)所產(chǎn)生的結(jié)果是不會被其他用戶更改的星压。

(3)釋放鎖定的數(shù)據(jù)表,以便讓正在隊列中等待查看或操作的其他用戶可以瀏覽數(shù)據(jù)表中的數(shù)據(jù)或?qū)Σ僮鞅韴?zhí)行各種數(shù)據(jù)的操作鬼譬。

如果存在其他會話要求訪問已鎖定的多個表格娜膘,則該會話必須被迫等待當前鎖定用戶釋放鎖定表。才允許其他會話訪問該數(shù)據(jù)表拧簸,表鎖定使不同會話執(zhí)行的數(shù)據(jù)庫操作彼此獨立劲绪。應(yīng)用數(shù)據(jù)表鎖定方式可以使不支持事務(wù)類型的表實現(xiàn)偽事務(wù)。

MySql的事務(wù)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末盆赤,一起剝皮案震驚了整個濱河市贾富,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌牺六,老刑警劉巖颤枪,帶你破解...
    沈念sama閱讀 206,013評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異淑际,居然都是意外死亡畏纲,警方通過查閱死者的電腦和手機扇住,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盗胀,“玉大人艘蹋,你說我怎么就攤上這事∑被遥” “怎么了女阀?”我有些...
    開封第一講書人閱讀 152,370評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長屑迂。 經(jīng)常有香客問我浸策,道長,這世上最難降的妖魔是什么惹盼? 我笑而不...
    開封第一講書人閱讀 55,168評論 1 278
  • 正文 為了忘掉前任庸汗,我火速辦了婚禮,結(jié)果婚禮上手报,老公的妹妹穿的比我還像新娘蚯舱。我一直安慰自己,他們只是感情好昧诱,可當我...
    茶點故事閱讀 64,153評論 5 371
  • 文/花漫 我一把揭開白布晓淀。 她就那樣靜靜地躺著,像睡著了一般盏档。 火紅的嫁衣襯著肌膚如雪凶掰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,954評論 1 283
  • 那天蜈亩,我揣著相機與錄音懦窘,去河邊找鬼。 笑死稚配,一個胖子當著我的面吹牛畅涂,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播道川,決...
    沈念sama閱讀 38,271評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼午衰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了冒萄?” 一聲冷哼從身側(cè)響起臊岸,我...
    開封第一講書人閱讀 36,916評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎尊流,沒想到半個月后帅戒,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,382評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡崖技,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,877評論 2 323
  • 正文 我和宋清朗相戀三年逻住,在試婚紗的時候發(fā)現(xiàn)自己被綠了钟哥。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 37,989評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡瞎访,死狀恐怖腻贰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情装诡,我是刑警寧澤银受,帶...
    沈念sama閱讀 33,624評論 4 322
  • 正文 年R本政府宣布践盼,位于F島的核電站鸦采,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏咕幻。R本人自食惡果不足惜渔伯,卻給世界環(huán)境...
    茶點故事閱讀 39,209評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望肄程。 院中可真熱鬧锣吼,春花似錦、人聲如沸蓝厌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拓提。三九已至读恃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間代态,已是汗流浹背寺惫。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蹦疑,地道東北人西雀。 一個月前我還...
    沈念sama閱讀 45,401評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像歉摧,于是被迫代替她去往敵國和親艇肴。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,700評論 2 345

推薦閱讀更多精彩內(nèi)容