最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL事務(wù)(transaction)看這篇就足夠了

 更新時間:2022年11月01日 12:27:33   作者:單節(jié)狂砍30分的胡亦  
M事務(wù)的實(shí)現(xiàn)是基于數(shù)據(jù)庫的存儲引擎,不同的存儲引擎對事務(wù)的支持程度不一樣,下面這篇文章主要給大家介紹了關(guān)于MySQL事務(wù)(transaction)的相關(guān)資料,需要的朋友可以參考下

MySQL事務(wù)處理(TransAction)

思考了很久,決定寫一篇關(guān)于mysql事務(wù)(transaction)的博客,一來嘛,因?yàn)樽罱趶?fù)習(xí)mysql的相關(guān)知識,幫自己回顧總結(jié)一下,其次就是想把這篇博客分享給大家,如果你才剛剛開始學(xué)習(xí)mysql,那么希望這篇博客對你有一點(diǎn)啟發(fā);亦或者你早已是一個mysql老油條,這篇博客也會使你對mysql事務(wù)有一個更深的印象。

首先,什么是事務(wù)呢?

事務(wù)就是由單獨(dú)單元的一個或多個sql語句組成,在這個單元中,每個sql語句都是相互依賴的。而整個單獨(dú)單元是作為一個不可分割的整體存在,類似于物理當(dāng)中的原子(一種不可分割的最小單位)。

往通俗的講就是,事務(wù)就是一個整體,里面的內(nèi)容要么都執(zhí)行成功,要么都不成功。不可能存在部分執(zhí)行成功而部分執(zhí)行不成功的情況。

就是說如果單元中某條sql語句一旦執(zhí)行失敗或者產(chǎn)生錯誤,那么整個單元將會回滾(返回最初狀態(tài))。所有受到影響的數(shù)據(jù)將返回到事務(wù)開始之前的狀態(tài),但是如果單元中的所有sql語句都執(zhí)行成功的話,那么該事務(wù)也就被順利執(zhí)行。

大家都知道,我們的數(shù)據(jù)都是通過各種不同技術(shù)的存儲引擎來引導(dǎo)存儲的,不同的存儲引擎,都有各自的特點(diǎn)。在mysql中,常見的存儲引擎有innodb、myisam,memory等。其中innodb支持事務(wù)(transaction),而myisam,memory等不支持事務(wù)。

可以通過show engines;語句來查看mysql支持的存儲引擎

一、事務(wù)的四個特性(ACID)【面試??柬?xiàng)】

  • 原子性(Atomicity):指事務(wù)是一個不可分割的最小工作單位,事務(wù)中的操作只有都發(fā)生和都不發(fā)生兩種情況
  • 一致性(Consistency):事務(wù)必須使數(shù)據(jù)庫從一個一致狀態(tài)變換到另外一個一致狀態(tài),舉一個栗子,李二給王五轉(zhuǎn)賬50元,其事務(wù)就是讓李二賬戶上減去50元,王五賬戶上加上50元;一致性是指其他事務(wù)看到的情況是要么李二還沒有給王五轉(zhuǎn)賬的狀態(tài),要么王五已經(jīng)成功接收到李二的50元轉(zhuǎn)賬。而對于李二少了50元,王五還沒加上50元這個中間狀態(tài)是不可見的。
  • 隔離性(Isolation):一個事務(wù)的執(zhí)行不能被其他事務(wù)干擾,即一個事務(wù)內(nèi)部的操作及使用的數(shù)據(jù)對并發(fā)的其他事務(wù)是隔離的,并發(fā)執(zhí)行的各個事務(wù)之間不能互相干擾。
  • 持久性(Durability):一個事務(wù)一旦提交成功,它對數(shù)據(jù)庫中數(shù)據(jù)的改變將是永久性的,接下來的其他操作或故障不應(yīng)對其有任何影響。

二、事務(wù)的分類

事務(wù)分為隱式事務(wù)和顯式事務(wù)兩種。我們的DML語句(insert、update、delete)就是隱式事務(wù)。

1.隱式事務(wù):該事務(wù)沒有明顯的開啟和結(jié)束標(biāo)記,它們都具有自動提交事務(wù)的功能;不妨思考一下,update語句修改數(shù)據(jù)時,是不是對表中數(shù)據(jù)進(jìn)行改變了,它的本質(zhì)其實(shí)就相當(dāng)于一個事務(wù)。

舉一個栗子:張三同學(xué)買了一個csdn定制保溫杯花了99元,是不是就是update語句對字段name為張三的同學(xué)的余額balance進(jìn)行減99元的處理呢?代碼如下:

2.顯示事務(wù):該事務(wù)具有明顯的開啟和結(jié)束標(biāo)記;也是本文重點(diǎn)要講的東西。使用顯式事務(wù)的前提是你得先把自動提交事務(wù)的功能給禁用。禁用自動提交功能就是設(shè)置autocommit變量值為0(0:禁用 1:開啟)

先查看一下當(dāng)前的autocommit變量值,發(fā)現(xiàn)當(dāng)前處于開啟自動提交事務(wù)的狀態(tài)

禁用自動提交事務(wù)的功能并查看當(dāng)前狀態(tài)

三、開啟事務(wù)的步驟

假設(shè)t_account表已經(jīng)存在

#步驟一:開啟事務(wù)(可選)
start transaction;
#步驟二:編寫事務(wù)中的sql語句(insert、update、delete)
#這里實(shí)現(xiàn)一下"李二給王五轉(zhuǎn)賬"的事務(wù)過程
update t_account set balance = 50 where vname = "李二";
update t_account set balance = 130 where vname = "王五";
#步驟三:結(jié)束事務(wù)
commit; #提交事務(wù)
# rollback; #回滾事務(wù):就是事務(wù)不執(zhí)行,回滾到事務(wù)執(zhí)行前的狀態(tài)

運(yùn)行結(jié)果:

四、事務(wù)并發(fā)時出現(xiàn)的問題

但是呢,因?yàn)槟骋豢滩豢赡芸傊挥幸粋€事務(wù)在運(yùn)行,可能出現(xiàn)A在操作t_account表中的數(shù)據(jù),B也同樣在操作t_account表,那么就會出現(xiàn)并發(fā)問題,對于同時運(yùn)行的多個事務(wù),當(dāng)這些事務(wù)訪問數(shù)據(jù)庫中相同的數(shù)據(jù)時,如果沒有采用必要的隔離機(jī)制,就會發(fā)生以下各種并發(fā)問題。

  1. ??臟讀:對于兩個事務(wù)T1,T2,T1讀取了已經(jīng)被T2更新但還沒有被提交的字段之后,若T2回滾,T1讀取的內(nèi)容就是臨時且無效的
  2. ??不可重復(fù)讀 :對于兩個事務(wù)T1,T2,T1讀取了一個字段,然后T2更新了該字段之后,T1在讀取同一個字段,值就不同了
  3. ?? 幻讀:對于兩個事務(wù)T1,T2,T1在A表中讀取了一個字段,然后T2又在A表中插入了一些新的數(shù)據(jù)時,T1再讀取該表時,就會發(fā)現(xiàn)神不知鬼不覺的多出幾行了…

所以,為了避免以上出現(xiàn)的各種并發(fā)問題,我們就必然要采取一些手段。mysql數(shù)據(jù)庫系統(tǒng)提供了四種事務(wù)的隔離級別,用來隔離并發(fā)運(yùn)行各個事務(wù),使得它們相互不受影響,這就是數(shù)據(jù)庫事務(wù)的隔離性。

五、事務(wù)的隔離級別

mysql中的四種事務(wù)隔離級別如下:

1. read uncommitted(讀未提交數(shù)據(jù)):允許事務(wù)讀取未被其他事務(wù)提交的變更。(臟讀、不可重復(fù)讀和幻讀的問題都會出現(xiàn))。

2. read committed(讀已提交數(shù)據(jù)):只允許事務(wù)讀取已經(jīng)被其他事務(wù)提交的變更。(可以避免臟讀,但不可重復(fù)讀和幻讀的問題仍然可能出現(xiàn))

3.repeatable read(可重復(fù)讀):確保事務(wù)可以多次從一個字段中讀取相同的值,在這個事務(wù)持續(xù)期間,禁止其他事務(wù)對這個字段進(jìn)行更新(update)。(可以避免臟讀和不可重復(fù)讀,但幻讀仍然存在)

4. serializable(串行化):確保事務(wù)可以從一個表中讀取相同的行,在這個事務(wù)持續(xù)期間,禁止其他事務(wù)對該表執(zhí)行插入、更新和刪除操作,所有并發(fā)問題都可避免,但性能十分低下(因?yàn)槟悴煌瓿删投疾豢梢耘?,效率太低?/p>

了解: oracle支持兩種事務(wù)隔離級別:read committed、serializable。

oracle默認(rèn)的事務(wù)隔離級別是:read committed。

mysql的默認(rèn)事務(wù)隔離級別是:repeatable read。

一個事務(wù)與其他事務(wù)隔離的程度稱為隔離級別。數(shù)據(jù)庫規(guī)定了多種事務(wù)隔離級別,不同隔離級別對應(yīng)不同的干擾程度,隔離級別越高,數(shù)據(jù)一致性就越好,但并發(fā)性就越差。

這里通過一個例子向大家簡單介紹一下并發(fā):

一個人?? 在邊開車?? 邊打電話??,首先,人只有一個大腦(cpu),但是在同一時刻他卻在執(zhí)行2件事情,其實(shí)內(nèi)部就是靠他的大腦在不斷的切換執(zhí)行,之所以人民警察?? 不允許司機(jī)開車時打電話,就是怕人腦在那一瞬間切換不過來,從而導(dǎo)致交通事故的發(fā)生,并發(fā)和這個例子是差不多的意思。但在這里,電腦cpu可比人腦快多了,所以出錯的概率也相對來說小很多。

接一下,演示一下在幾種不同的事務(wù)隔離級別下所發(fā)生的不同情況?? 。

在演示之前呢,還需要知道如何查看和設(shè)置事務(wù)的隔離級別

查看當(dāng)前的事務(wù)隔離級別通過 tx_isolation變量或者transaction_isolation(版本8.0以上使用);

語法:select @@tx_isolation;

注意:在mysql8.0之后,就已經(jīng)拋棄了tx_isolation變量了,而是用 transaction_isolation變量代替了。

語法:select @@transaction_isolation;

#設(shè)置當(dāng)前mysql連接的隔離級別:
set session transaction isolation level read uncommitted;
#設(shè)置數(shù)據(jù)庫系統(tǒng)的全局的隔離級別:
set global transaction isolation level read uncommitted;

注意:當(dāng)前mysql連接的隔離級別和mysql全局的隔離級別的區(qū)別是什么?

如果只設(shè)置當(dāng)前的隔離級別,也就是session,那么另外一個并發(fā)的“mysqy程序”的隔離級別不會受到當(dāng)前連接的影響,而是保持默認(rèn)的repeatable read。

但是如果是設(shè)置全局的事務(wù)隔離級別,則整個mysql數(shù)據(jù)庫(包括所有打開的mysql程序連接)的隔離級別都會隨之改變,除非服務(wù)器重啟,不然就不會恢復(fù)默認(rèn)了。

兩者僅僅一詞之差,其效果卻天差地別。

好,了解完如何設(shè)置事務(wù)的隔離級別之后,下面將正式進(jìn)入…

呃呃呃… 等一下

這里的講解主要是為了知道在并發(fā)的環(huán)境下,不同的事務(wù)隔離級別所表現(xiàn)出的不同特點(diǎn),那么自然還是要先模擬一下并發(fā)環(huán)境

這里打開兩個獨(dú)立的mysql數(shù)據(jù)庫連接(mysql程序1和mysql程序2),用來模擬并發(fā)環(huán)境

咳咳咳… 正片開始

同志們打起精神認(rèn)真看?。。?/p>

  • read uncommitted(讀未提交)

首先,我們需要先將兩個會話的事務(wù)隔離級別都設(shè)置為read uncommitted;語句如下:

read uncommitted可以讀到其他事務(wù)還沒提交的變更,這里舉例:程序2對t_account表中的數(shù)據(jù)進(jìn)行更改,看程序1多次查詢的結(jié)果是否一致。

可以看到程序2改變了t_account表中的vname字段,將李二改為了張三。但是程序1呢,連續(xù)2個select查詢語句的結(jié)果竟然不一致,估計現(xiàn)在程序1的表情和你手機(jī)里的第三個表情包一樣。這就是read uncommitted隔離級別的特點(diǎn)。
不管你事務(wù)是否提交,只要數(shù)據(jù)發(fā)生改變我就可以察覺到…嘻嘻。是不是感覺它很強(qiáng)大。什么事情都逃不過它的法眼。

接下來要看的是read committed(讀已提交)

  • read committed(讀已提交)

測試前一定要記住設(shè)置事務(wù)的隔離級別為read committed;并且禁用自動提交事務(wù)【設(shè)置autocommit為0】(后面的每個測試都是一樣的)

# 設(shè)置事務(wù)隔離級別為read committed
set session transaction isolation level read committed;
# 禁用自動提交事務(wù)功能
set autocommit = 0; 
#接下來的 repeatable read 隔離級別和 serializable 隔離級別也是同樣的操作

以上例子實(shí)現(xiàn)了王五為張三轉(zhuǎn)賬的事務(wù),可以看到程序2中事務(wù)提交前與提交后對程序1中的查詢語句產(chǎn)生的影響,前2個查詢是事務(wù)沒提交的結(jié)果,最后一個查詢是事務(wù)提交后的結(jié)果。 相信上面的例子已經(jīng)很充分的詮釋了read committed的特點(diǎn)。

  • repeatable read(可重復(fù)讀)

該隔離級別為mysql的默認(rèn)隔離級別;它對某字段進(jìn)行操作時,其他事務(wù)禁止操作該字段。它總能保持你讀取的數(shù)據(jù)是一致的。

以下代碼中,程序1模擬"王五向張三轉(zhuǎn)賬30元",程序2則在程序1在處理事務(wù)時,對張三的余額進(jìn)行清空處理

因?yàn)楫?dāng)前的事務(wù)隔離級別為repeatable read級別,所以在程序1操作t_account表時,程序2是無權(quán)對t_account表進(jìn)行任何操作,如果強(qiáng)行操作的話,就會發(fā)生error (錯誤)

“ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction”;

其中文意思是:“超過鎖定等待超時;嘗試重新啟動事務(wù)”

只有當(dāng)程序1對t_account表操作完成后(結(jié)束事務(wù)后),程序2才可以對t_account表進(jìn)行操作。

  • serializable(串行化)

該隔離模式下執(zhí)行的事務(wù)在對某表進(jìn)行操作期間,禁止其他所有事務(wù)對該表進(jìn)行任何操作

如果強(qiáng)行操作也會報錯(和上面那個錯誤一致),因?yàn)閟erializable用的相對比較少,這里就不做演示了。同學(xué)們理解了就好。

  • 事務(wù)的保存點(diǎn)(回滾點(diǎn))

回滾點(diǎn)表示的就是使事務(wù)回滾到指定回滾點(diǎn)

語法: savepoint 節(jié)點(diǎn)名稱 ;

注意:保存點(diǎn)只允許搭配rollback回滾來使用,不能和commit一起使用

已知表t_stu存在,其數(shù)據(jù)如下:

代碼舉例如下:

 #禁用自動提交事務(wù)
set autocommit = 0;
 #開啟事務(wù)
start transaction;
 #刪除id為2的記錄
delete from t_stu where id = 2;
 #設(shè)置保存點(diǎn)名為AA
savepoint AA;
 #刪除id為3的記錄
delete from t_stu where id = 3;
  #回滾到AA保存點(diǎn)處
rollback to AA;

運(yùn)行結(jié)果如下:

可以看到id為2的李四被刪除了,而王五卻還在,就是因?yàn)槭聞?wù)回滾到了AA處,所以id為3的那條記錄被回滾掉了。

總結(jié)

到此這篇關(guān)于MySQL事務(wù)(transaction)的文章就介紹到這了,更多相關(guān)MySQL事務(wù)transaction內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 簡單了解標(biāo)準(zhǔn)SQL的update語句三種用法

    簡單了解標(biāo)準(zhǔn)SQL的update語句三種用法

    這篇文章主要介紹了簡單了解標(biāo)準(zhǔn)SQL的update語句三種用法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,,需要的朋友可以參考下
    2019-06-06
  • mysql表的內(nèi)連和外連實(shí)戰(zhàn)記錄

    mysql表的內(nèi)連和外連實(shí)戰(zhàn)記錄

    在開發(fā)中我們的業(yè)務(wù)需求有時候是復(fù)雜的,多張表聯(lián)合查詢的時候是有多種方式的,面對不同的需求,靈活使用不同的表連接方式,這篇文章主要給大家介紹了關(guān)于mysql表內(nèi)連和外連的相關(guān)資料,需要的朋友可以參考下
    2024-01-01
  • MySQL記錄操作日志常用的幾種實(shí)現(xiàn)方法

    MySQL記錄操作日志常用的幾種實(shí)現(xiàn)方法

    這篇文章主要介紹了MySQL記錄操作日志常用的幾種實(shí)現(xiàn)方法,文中介紹的方法包括啟用通用查詢?nèi)罩?、二進(jìn)制日志、使用審計插件和觸發(fā)器,每種方法都有其適用場景和優(yōu)缺點(diǎn),選擇合適的方法可以有效跟蹤和管理數(shù)據(jù)庫操作,需要的朋友可以參考下
    2024-11-11
  • MySQL 實(shí)現(xiàn)雙向復(fù)制的方法指南

    MySQL 實(shí)現(xiàn)雙向復(fù)制的方法指南

    這篇文章主要介紹了MySQL 實(shí)現(xiàn)雙向復(fù)制的方法指南,本文包括:主機(jī)配置,從機(jī)配置,建立主-從復(fù)制,建立雙向復(fù)制,需要的朋友可以參考下
    2015-03-03
  • 如何使Mysql自動生成序號列,序號自動增長問題

    如何使Mysql自動生成序號列,序號自動增長問題

    這篇文章主要介紹了如何使Mysql自動生成序號列,序號自動增長問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • mysql8.0忘記密碼的詳細(xì)解決方法

    mysql8.0忘記密碼的詳細(xì)解決方法

    很早前安裝了MYSQL,現(xiàn)在由于需要使用MYSQL但忘記密碼,所以下面這篇文章主要給大家介紹了關(guān)于mysql8.0忘記密碼的詳細(xì)解決方法,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • MySQL對字符串使用STR_TO_DATE()函數(shù)詳解

    MySQL對字符串使用STR_TO_DATE()函數(shù)詳解

    文章介紹了MySQL中的STR_TO_DATE()函數(shù),用于將字符串轉(zhuǎn)換為日期時間類型,轉(zhuǎn)換時需要注意字符串格式、日期有效性等問題
    2025-03-03
  • PHP學(xué)習(xí)散記 2012_01_07(MySQL)

    PHP學(xué)習(xí)散記 2012_01_07(MySQL)

    數(shù)據(jù)庫是Web大多數(shù)應(yīng)用開發(fā)的基礎(chǔ)。如果你是用PHP,那么大多數(shù)據(jù)庫用的是MYSQL也是LAMP架構(gòu)的重要部分
    2012-01-01
  • MySQL UPDATE 語句一個“經(jīng)典”的坑

    MySQL UPDATE 語句一個“經(jīng)典”的坑

    這篇文章主要介紹了MySQL UPDATE 語句一個“經(jīng)典”的坑,一個非常有意思的話題,感興趣的小伙伴可以參考下面文章的具體內(nèi)容哦
    2021-10-10
  • MySQL的DML語言操作實(shí)例

    MySQL的DML語言操作實(shí)例

    在本篇文章里小編給大家整理的是一篇關(guān)于MySQL的DML語言操作實(shí)例內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。
    2020-02-02

最新評論

涟源市| 井陉县| 定兴县| 五大连池市| 金华市| 宁阳县| 九台市| 岳普湖县| 丰宁| 沧州市| 马关县| 大足县| 永定县| 若羌县| 青铜峡市| 铜川市| 疏勒县| 开化县| 陵水| 西和县| 梧州市| 石景山区| 南阳市| 栾城县| 沂源县| 南宁市| 东至县| 南乐县| 遂溪县| 贵港市| 临海市| 含山县| 高安市| 南江县| 得荣县| 丹巴县| 万盛区| 肃宁县| 张家港市| 桐城市| 平顺县|