日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

mysql怎么实现事务序列化_MySQL 架构 - 事务处理

發(fā)布時(shí)間:2025/4/16 数据库 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql怎么实现事务序列化_MySQL 架构 - 事务处理 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

事務(wù)處理

在事務(wù)處理之前,你不能知道數(shù)據(jù)庫(kù)系統(tǒng)有如此多的高級(jí)功能。一個(gè)事物就是一組SQL查詢。這一組被看做是原子的。也就是一個(gè)單獨(dú)的工作單元。如果數(shù)據(jù)庫(kù)引擎可以應(yīng)用整個(gè)組的查詢,就執(zhí)行完畢。但是如果其中一條語(yǔ)句出現(xiàn)問(wèn)題,整個(gè)組的語(yǔ)句都不會(huì)被執(zhí)行。也就是要么全部執(zhí)行,要么全部不執(zhí)行。

這部分所講到的事物很少是針對(duì)MySQL的,如果你已經(jīng)熟悉了ACID事務(wù)處理,可以跳過(guò)這一部分。

銀行的應(yīng)用是解釋為什么需要事務(wù)處理的經(jīng)典案例。假設(shè)銀行數(shù)據(jù)有兩張表。checking以及savings.從Jane的checking賬戶轉(zhuǎn)賬200到她的saving賬戶。至少要三步

確定她的checking賬戶至少有200

從checking賬戶扣除200

把200添加到她的savings賬戶中。

整個(gè)操作封裝為了一個(gè)事物。因此其中一個(gè)操作失敗,整個(gè)操作都會(huì)回滾。

開(kāi)始一個(gè)事物的語(yǔ)句是START TRANSACTION以及修改成功用COMMIT或者放棄改變用ROLLBACK。因此這個(gè)例子的SQL語(yǔ)句如下

START TRANSACTION;

SELECT balance FROM checking WHERE customer_id = 10233276;

UPDATE checking SET balance = balance - 200.00 WHERE customer_id = 10233276;

UPDATE savings SET balance = balance + 200.00 WHERE customer_id = 10233276;

COMMIT;

但是單獨(dú)的事物并不能代表全部。如果在數(shù)據(jù)庫(kù)服務(wù)器在執(zhí)行到第四行的時(shí)候掛掉呢?用戶可能就白白損失了200。以及如果有個(gè)處理出現(xiàn)在了3,4行之間,而不會(huì)去扣除checking帳戶的余額。那么銀行就白白給了用戶200.

在系統(tǒng)沒(méi)有通過(guò)ACID的測(cè)試之前,僅僅有事物還是不夠的。ACID的意思是原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)。這些都是一個(gè)好的事務(wù)處理系統(tǒng)所要遵循的標(biāo)準(zhǔn)。

原子性(Atomicity):

一個(gè)事物必須做為一個(gè)單獨(dú)不可分割的工作單元來(lái)運(yùn)行。因此整個(gè)事物要么全部成功要么全部失敗。當(dāng)事物具有原子性的時(shí)候,不能一部分的執(zhí)行。要么全部執(zhí)行,要么全部失敗。

一致性(Consistency):

數(shù)據(jù)庫(kù)應(yīng)該總是從一個(gè)一致的狀態(tài)到另一個(gè)。在我們的例子中,一致性要確保程序在3,4行崩潰并不會(huì)使checking帳戶減少200。因?yàn)槭挛餂](méi)有提交。數(shù)據(jù)庫(kù)沒(méi)有任何變化。

隔離性(Isolation):

當(dāng)這個(gè)事物沒(méi)有完成的時(shí)候,它的結(jié)果對(duì)于其他的事物是不可見(jiàn)的。這點(diǎn)確保了在運(yùn)行完第3行,以及在第4行之前。200還是在checking帳戶中。當(dāng)我們討論隔離性的時(shí)候,我們常常用到不可見(jiàn)(invisible)這個(gè)詞。

持久性(Durability):

當(dāng)事物提交,這個(gè)事物的改變就被持久化了。意思就是更改被記錄了。數(shù)據(jù)不會(huì)丟失了。持久性是個(gè)挺模糊的概念。因?yàn)樗泻芏嗉?jí)別。一些持久性策略比其他的有更強(qiáng)的安全性保證。但是絕對(duì)沒(méi)有100%的持久。我們會(huì)在以后的章節(jié)討論在MySQL中持久性的意思。

ACID事物保證了銀行不會(huì)損失錢(qián)。這點(diǎn)在業(yè)務(wù)邏輯上很難或者根本做不到。一個(gè)有ACID的數(shù)據(jù)庫(kù)服務(wù)器已經(jīng)把各種各樣復(fù)雜的事情都解決了,使你沒(méi)有必要自己去確保ACID。

隨著鎖的顆粒度上升,數(shù)據(jù)庫(kù)服務(wù)器要在安全性上做更多的工作了。數(shù)據(jù)庫(kù)的ACID事物也需要更多的CPU,內(nèi)存,硬盤(pán)空間。我們多次說(shuō)過(guò)MySQL存儲(chǔ)引擎架構(gòu)的優(yōu)勢(shì)。你可以決定到底是否使用事物。如果不需要可以選擇更好的沒(méi)有事務(wù)支持的存儲(chǔ)引擎。在沒(méi)有事物的時(shí)候,你可以使用LOCK TABLES來(lái)保護(hù)數(shù)據(jù)。決定權(quán)在于你。

隔離級(jí)別

隔離要比看上去復(fù)雜的多。SQL定義了4種隔離級(jí)別。這些規(guī)則讓更改對(duì)事物的內(nèi)部和外部可見(jiàn)和不可見(jiàn)。低級(jí)別的隔離可以高并發(fā)低消耗。

(每個(gè)存儲(chǔ)引擎的隔離級(jí)別實(shí)現(xiàn)都是不同的,如果你過(guò)去經(jīng)常使用其他數(shù)據(jù)庫(kù)產(chǎn)品,存儲(chǔ)引擎不一定符合你的需求,你應(yīng)該看手冊(cè)決定使用哪個(gè)存儲(chǔ)引擎。)

未提交讀(READ UNCOMMITTED)

在這個(gè)級(jí)別中,事物可以看到未提交事物的結(jié)果。這個(gè)級(jí)別有很多問(wèn)題會(huì)發(fā)生,除非你真的真的明白你在做什么以及有足夠的理由去做。這級(jí)別在實(shí)踐中很少使用。因?yàn)樾阅芟鄬?duì)于其他級(jí)別也沒(méi)什么優(yōu)勢(shì)。讀取未提交的數(shù)據(jù),也叫臟讀(dirty read)

已提交讀(READ COMMITTED)

有許多數(shù)據(jù)庫(kù)系統(tǒng)默認(rèn)的隔離級(jí)別都是已提交讀(MySQL并不是)。它滿足了早期使用的隔離簡(jiǎn)單定義:一個(gè)事物可以看到事物提交后的改變。這種改變?cè)谔峤恢皩?duì)于其他事物是不可見(jiàn)的。這級(jí)別也經(jīng)常叫做不可重復(fù)讀(nonrepeatable read)。意思就是你運(yùn)行同一語(yǔ)句兩次,可以看到不同的數(shù)據(jù)。

可重復(fù)讀(REPEATABLE READ)

可重復(fù)讀解決了未提交讀的問(wèn)題。它保證了在同一個(gè)事物中,連續(xù)任意行的讀的數(shù)據(jù)都是相同的。但這種方式也引起了其他惡心的問(wèn)題。幻讀(phantom reads.)。簡(jiǎn)單地說(shuō)就是,當(dāng)你選擇一定范圍的行,另一個(gè)事物想這個(gè)范圍新增加了一行。之后有查詢相同的范圍。你就會(huì)發(fā)現(xiàn)出現(xiàn)了像幻覺(jué)一樣的一行。InnoDB和Falcon用多版本并發(fā)控制來(lái)解決了幻讀的問(wèn)題。

可重復(fù)讀是MySQL默認(rèn)的事物隔離級(jí)別。InnoDB和Falcon也是遵循這個(gè)設(shè)置。以后會(huì)講到怎樣修改這個(gè)設(shè)置。其他的引擎也是這樣的,但是決定權(quán)在于引擎。

可序列化(SERIALIZABLE)

最高的隔離級(jí)別。解決的幻讀的問(wèn)題。強(qiáng)迫事物是有序的。因此他們不可能沖突。簡(jiǎn)單的意思就是可序列化把每一行加一個(gè)鎖。這一級(jí)別許多超時(shí)和鎖的競(jìng)爭(zhēng)將出現(xiàn)。我們很少看見(jiàn)人們使用這個(gè)級(jí)別的隔離。你的應(yīng)用也有可能強(qiáng)迫你把隔離級(jí)別設(shè)置那么高,而忽視并發(fā)性。重視數(shù)據(jù)的穩(wěn)定性。

隔離級(jí)別

臟讀

不可重復(fù)讀

幻讀

讀取鎖

未提交讀

已提交讀

可重復(fù)讀

可序列化

死鎖(Deadlocks)

死鎖就是當(dāng)兩個(gè)以上的事物相互的等待和請(qǐng)求同一資源,產(chǎn)生了循環(huán)依賴就導(dǎo)致死鎖。死鎖存在事物嘗試不同的順序去鎖定資源的時(shí)候。在任何時(shí)候多事物鎖定同一資源都會(huì)發(fā)生死鎖。舉個(gè)例子。。有兩個(gè)事物運(yùn)行在StockPrice的表。

事物一

START TRANSACTION;

UPDATE StockPrice SET close = 45.50 WHERE stock_id = 4 and date = '2002-05-01';

UPDATE StockPrice SET close = 19.80 WHERE stock_id = 3 and date = '2002-05-02';

COMMIT;

事物二

START TRANSACTION;

UPDATE StockPrice SET high = 20.12 WHERE stock_id = 3 and date = '2002-05-02';

UPDATE StockPrice SET high = 47.20 WHERE stock_id = 4 and date = '2002-05-01';

COMMIT;

如果你足夠的倒霉,可能會(huì)發(fā)生如下情況。每個(gè)事物都完成第一條語(yǔ)句更新了StockPrice表。給它加了鎖。每個(gè)事物都試圖執(zhí)行第二行。發(fā)現(xiàn)它被加鎖了。這兩個(gè)事物都會(huì)等待除自己另外一個(gè)事物結(jié)束。除非有操作能破壞這個(gè)死鎖狀況。

為了解決這個(gè)問(wèn)題,數(shù)據(jù)庫(kù)系統(tǒng)實(shí)現(xiàn)了許多種死鎖的檢測(cè)和超時(shí)處理。在更復(fù)雜的系統(tǒng)中,如InnoDB存儲(chǔ)引擎。會(huì)發(fā)現(xiàn)循環(huán)依賴并且及時(shí)的返回錯(cuò)誤。真是非常好的方式,否則死鎖會(huì)降低語(yǔ)句的執(zhí)行效率。其他的方式是在鎖等待超時(shí)之后,放棄操作。這個(gè)方式不太好。InnoDB處理死鎖的方式是,回滾有最少行級(jí)鎖的事物。

鎖的行為和順序是存儲(chǔ)引擎特定的。因此有些存儲(chǔ)引擎可能在特定的一系列語(yǔ)句發(fā)生死鎖,其他的也許不會(huì)。死鎖有雙重特性:一些是不可避免的,因?yàn)榇_實(shí)是數(shù)據(jù)沖突。一些是由于存儲(chǔ)引擎工作方式所引起的。

事務(wù)日志

事物日志的幫助可以讓事物更有效率。存儲(chǔ)引擎更改存儲(chǔ)在內(nèi)存中的數(shù)據(jù)拷貝,取代每次修改都要更新硬盤(pán)上的表。這種方法非常高效。之后,存儲(chǔ)引擎就向事務(wù)日志添加一條記錄。這個(gè)日志存放在硬盤(pán)中,因此是持久的。這個(gè)操作相對(duì)來(lái)說(shuō)能快點(diǎn)。因?yàn)楦郊佑涗浭录褂眯》秶倪B續(xù)IO取代了大范圍的隨機(jī)IO。之后,在晚一點(diǎn),會(huì)更新硬盤(pán)上的表。所以大部分存儲(chǔ)引擎都使用這個(gè)技術(shù)(write-ahead logging 預(yù)寫(xiě)式記錄),會(huì)兩次向硬盤(pán)寫(xiě)入更改的信息。

在更新日志之后,更改數(shù)據(jù)之前發(fā)生了錯(cuò)誤。存儲(chǔ)引擎仍然在重啟后恢復(fù)更改。各個(gè)存儲(chǔ)引擎的恢復(fù)方法各不相同。

MySQL中的事物

MySQL提供了三種支持事物的存儲(chǔ)引擎:?InnoDB, NDB Cluster, Falcon。許多第三方的引擎也可以使用,比較有名的就是solidDB 以及PBXT。在下一部分會(huì)詳細(xì)介紹這些存儲(chǔ)引擎。

AUTOCOMMIT

MySQL的AUTOCOMMIT是默認(rèn)的。意思就是無(wú)論你是否開(kāi)始一個(gè)事物,在每個(gè)語(yǔ)句都會(huì)自動(dòng)執(zhí)行。當(dāng)然你可以設(shè)置這個(gè)AUTOCOMMIT的變量,方法如下

1和ON是一樣的。0也就是OFF。當(dāng)AUTOCOMMIT=0的時(shí)候,你必須COMMIT或ROLLBACK,不然的話你就總在一個(gè)事物中,語(yǔ)句不會(huì)執(zhí)行。如果表的存儲(chǔ)引擎不支持事物,改變AUTOCOMMIT的值,不會(huì)有任何的效果。這些存儲(chǔ)引擎是MyISAM或者M(jìn)emory.它們總是自動(dòng)提交。

一些命令,當(dāng)開(kāi)始一個(gè)事物,在執(zhí)行之前,MySQL會(huì)自動(dòng)提交事物。這些命令就是DDL。如果ALTER TABLE等,還有一些特殊如LOCK TABLES也會(huì)有這樣的效果。具體的查看數(shù)據(jù)庫(kù)版本的文檔。來(lái)查看哪些命令是自動(dòng)提交的。

MySQL允許設(shè)置隔離級(jí)別。命令是SET TRANSACTION ISOLATION LEVEL 。這會(huì)影響下一個(gè)事物的開(kāi)始時(shí)間。你也可以通過(guò)配置文件來(lái)設(shè)置整個(gè)服務(wù)器的隔離級(jí)別,這個(gè)將在以后說(shuō)。也可以針對(duì)當(dāng)前會(huì)話。如

mysql> SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

MySQL能識(shí)別所有標(biāo)準(zhǔn)的隔離級(jí)別,以及InnoDB存儲(chǔ)引擎支持這些隔離級(jí)別。其他的存儲(chǔ)引擎不同程度上支持不同的隔離級(jí)別。

在事物中混合使用存儲(chǔ)引擎

在服務(wù)器級(jí)別,MySQL不能管理事物。而事物是由存儲(chǔ)引擎所實(shí)現(xiàn)的。意思就是你不能在一個(gè)單獨(dú)事物中混合使用不同的存儲(chǔ)引擎。MySQL AB給服務(wù)器添加了一個(gè)更高級(jí)別的事務(wù)管理服務(wù)。這樣就會(huì)在一個(gè)事物中,混合和匹配事務(wù)表更加安全。在此之前一定要小心。

如果在一個(gè)事物中混合了事物和非事物表。如果一切正常,這個(gè)事物就沒(méi)有問(wèn)題,但是如果執(zhí)行回滾操作,非事物表改變的數(shù)據(jù)并不會(huì)回滾。數(shù)據(jù)庫(kù)的一致性遭到了破壞,很難恢復(fù)和呈現(xiàn)完整的事物。這就是為什么給表選擇存儲(chǔ)引擎是如此的重要。

如果你在非事物表上做事物操作,MySQL并不會(huì)提示或者拋出異常。有的時(shí)候,回滾會(huì)有一定的提示。“Some nontransactional changed tables couldn’t be rolled back”。但是一般都不會(huì)有什么提示。

隱式和顯式的鎖定

InnoDB使用兩階段鎖定協(xié)議(two-phase locking protocol)。它能任意時(shí)間在一個(gè)事物之中獲得鎖。但是只要執(zhí)行COMMIT或ROLLBACK才會(huì)釋放鎖。它總在同一時(shí)刻釋放鎖。鎖機(jī)制的描述都是隱式的。InnoDB根據(jù)你設(shè)置的隔離級(jí)別自動(dòng)處理鎖。

然而,InnoDB也支持顯式加鎖。SQL的標(biāo)準(zhǔn)并沒(méi)有提到:

? SELECT ... LOCK IN SHARE MODE

? SELECT ... FOR UPDATE

MySQL也支持LOCK TABLES 和UNLOCK TABLES命令。這個(gè)是由服務(wù)器實(shí)現(xiàn)的。并不是存儲(chǔ)引擎。這個(gè)可以使用,但它并不不能取代事物。如果你要用事物,請(qǐng)使用支持事物的存儲(chǔ)引擎。

我們看到很多應(yīng)用從MyISAM轉(zhuǎn)到InnoDB,但是還在使用LOCK TABLES.這沒(méi)什么必要,因?yàn)樾屑?jí)別的鎖定。LOCK TABLE也會(huì)引起性能問(wèn)題。

(LOCK TABLES和事物之間的交互是復(fù)雜的。可能有些意想不到的異常出現(xiàn)。所以我們建議除非你不使用事物和把AUTOCOMMIT關(guān)閉,否則永遠(yuǎn)不要使用LOCK TABLES。)

大小: 17.8 KB

分享到:

2009-06-01 17:01

瀏覽 1859

評(píng)論

總結(jié)

以上是生活随笔為你收集整理的mysql怎么实现事务序列化_MySQL 架构 - 事务处理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。