淺談事務(一)
關於事務,在Oracle中似乎是習以為常的,但是在學習MySQL的過程中,發現各種靈活的儲存引擎,一個很大的焦點就是對於事務的支援,足以看出事務的實現還是有一定難度的,自己在學習資料庫理論和Oracle的時候,對於事務的特性也都是一筆帶過,ACID似乎就是書本中的概念和術語,感覺太偏向理論了,但是今天在學習看書中,也借鑑了不少寶貴的經驗,重新審視來發現事務的強大和重要性。
好多書中都會提到的ACID,先來看看是怎麼說的。
原子性:Atomicity,一致性:Consistency,隔離性:Isolation,永續性:Durability
舉個例子來說明,比如使用銀行卡轉賬,給某個朋友轉賬100塊,就需要執行幾個步驟:
首先會檢視銀行卡中的餘額是否滿足條件。
其次會從銀行卡中轉出100塊,
然後對方的銀行卡中會轉入100塊。
這個例子很簡單也很明顯,
首先原子性,就是這個轉賬的過程中,轉賬操作是一個不可再分的單元了,轉賬的的操作,卡1轉出成功,卡2轉入成功,整個過程要不全部完成,要不直接回退。
其次是一致性,就是在資料庫中,事務總是從一個一致性的狀態轉換為另外一個一致性的狀態,比如我們在操作的第2步,銀行卡轉出100塊的瞬間,系統奔潰,電腦當機,你的賬戶也不會平白無故少100塊錢。因為事務最終沒有提交,所做的修改也不會儲存在資料庫中。
再次是隔離性,這個一般來說,一個事務所做的修改,對其它事務是不可見的,這一點解釋起來稍微有些困難,先放一放。
最後一點是永續性,就是在資料庫中,所做的事務變更最後都儲存在資料庫中,這一點還是從邏輯上保證的。至少在Oracle中你做了commit不會立刻寫入資料檔案,也是一個非同步的過程。
ACID確實可以保證銀行卡里不會弄丟錢,但是在邏輯層面要實現這個事務還是很困難的,從MySQL的儲存引擎的發展就能看出,InnoDB儲存引擎相比MyISAM來說,對於資源的消耗和效能會有一定的打折,但是相比來說就更加有優勢。
其中一個難點就是隔離性,在SQL標準裡面也提供了4種隔離級別,每一種級別規定了在一個事務的修改過程中,哪些在事務間是可見的,哪些是不可見的。
比如我們用sql語句來表示兩個併發的事務。
事務1中開始檢視餘額,有1000塊,然後向卡里轉入100塊。在這個過程中事務1還是沒有提交,是否對於事務2可見這個1100塊新餘額。
如果從生活實際來考慮是不應該的。如果對於事務2可見,則這種情況下隔離級別就是未提交讀(READ COMMITED),就是我們常說的髒讀,當然這種隔離級別的開銷是很低的,但是會導致很多問題,所以一般的在實際應用還是比較少的。
然後我們進一步思考,如果事務1在充值100塊之後,在事務沒有提交之前,對於事務2是完全不可見的,這種隔離級別就是不可重複讀,或者提交讀(READ COMMITED),Oracle中就是採用這種隔離級別的。但是在MySQL中缺預設不是這種隔離級別。
我們來看看第三種隔離級別,可重複讀(REPEATABLE READ),這個級別保證了在同一個事務中多次讀取同樣的記錄的結果是一致的。
這種情況,事務1先充值100塊,這樣餘額就是1100,事務2充值100塊,餘額就是1200,但是在事務1未提交,所以再次查詢的時候還是顯示餘額1100,這種情況就是幻讀(Phantom Read)。
最後一種是最高階別,即可序列化(SERIALIZABLE),這種情況下會強制事務序列執行,可以避免幻讀的問題,但是他會在讀取的每一行資料上都加鎖,所以可能導致大量的效能問題。這種情況下使用的場景也很少。
在Oracle中可以使用set transaction isolation level 來指定四種隔離級別。
比如未提交讀,就可以執行
> set transaction isolation level read committed;
Transaction set.
好多書中都會提到的ACID,先來看看是怎麼說的。
原子性:Atomicity,一致性:Consistency,隔離性:Isolation,永續性:Durability
舉個例子來說明,比如使用銀行卡轉賬,給某個朋友轉賬100塊,就需要執行幾個步驟:
首先會檢視銀行卡中的餘額是否滿足條件。
其次會從銀行卡中轉出100塊,
然後對方的銀行卡中會轉入100塊。
這個例子很簡單也很明顯,
首先原子性,就是這個轉賬的過程中,轉賬操作是一個不可再分的單元了,轉賬的的操作,卡1轉出成功,卡2轉入成功,整個過程要不全部完成,要不直接回退。
其次是一致性,就是在資料庫中,事務總是從一個一致性的狀態轉換為另外一個一致性的狀態,比如我們在操作的第2步,銀行卡轉出100塊的瞬間,系統奔潰,電腦當機,你的賬戶也不會平白無故少100塊錢。因為事務最終沒有提交,所做的修改也不會儲存在資料庫中。
再次是隔離性,這個一般來說,一個事務所做的修改,對其它事務是不可見的,這一點解釋起來稍微有些困難,先放一放。
最後一點是永續性,就是在資料庫中,所做的事務變更最後都儲存在資料庫中,這一點還是從邏輯上保證的。至少在Oracle中你做了commit不會立刻寫入資料檔案,也是一個非同步的過程。
ACID確實可以保證銀行卡里不會弄丟錢,但是在邏輯層面要實現這個事務還是很困難的,從MySQL的儲存引擎的發展就能看出,InnoDB儲存引擎相比MyISAM來說,對於資源的消耗和效能會有一定的打折,但是相比來說就更加有優勢。
其中一個難點就是隔離性,在SQL標準裡面也提供了4種隔離級別,每一種級別規定了在一個事務的修改過程中,哪些在事務間是可見的,哪些是不可見的。
比如我們用sql語句來表示兩個併發的事務。
事務1中開始檢視餘額,有1000塊,然後向卡里轉入100塊。在這個過程中事務1還是沒有提交,是否對於事務2可見這個1100塊新餘額。
如果從生活實際來考慮是不應該的。如果對於事務2可見,則這種情況下隔離級別就是未提交讀(READ COMMITED),就是我們常說的髒讀,當然這種隔離級別的開銷是很低的,但是會導致很多問題,所以一般的在實際應用還是比較少的。
然後我們進一步思考,如果事務1在充值100塊之後,在事務沒有提交之前,對於事務2是完全不可見的,這種隔離級別就是不可重複讀,或者提交讀(READ COMMITED),Oracle中就是採用這種隔離級別的。但是在MySQL中缺預設不是這種隔離級別。
我們來看看第三種隔離級別,可重複讀(REPEATABLE READ),這個級別保證了在同一個事務中多次讀取同樣的記錄的結果是一致的。
這種情況,事務1先充值100塊,這樣餘額就是1100,事務2充值100塊,餘額就是1200,但是在事務1未提交,所以再次查詢的時候還是顯示餘額1100,這種情況就是幻讀(Phantom Read)。
最後一種是最高階別,即可序列化(SERIALIZABLE),這種情況下會強制事務序列執行,可以避免幻讀的問題,但是他會在讀取的每一行資料上都加鎖,所以可能導致大量的效能問題。這種情況下使用的場景也很少。
在Oracle中可以使用set transaction isolation level 來指定四種隔離級別。
比如未提交讀,就可以執行
> set transaction isolation level read committed;
Transaction set.
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29734436/viewspace-1623417/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 淺談資料庫事務資料庫
- 淺談ORACLE的分散式事務Oracle分散式
- mysql淺談--事務ACID特性MySql
- 談談 js 深淺拷貝 那點事(一)JS
- 淺談SQL Server中的事務日誌(一)----事務日誌的物理和邏輯構架SQLServer
- 談談Java事務Java
- 由事務擴充套件開談一談套件
- 淺談SQL Server中的事務日誌(轉載)SQLServer
- 淺談微服務微服務
- 談談分散式事務原理分散式
- 淺談、男人需要完成的事!
- 細談Mysql事務MySql
- MySQL事務原理淺析MySql
- 談談 js 深淺拷貝 那點事(二)JS
- 淺談Blazor開發的那些事Blazor
- 淺談 Java HashMap 的那點事JavaHashMap
- 淺談微服務轉型微服務
- 淺談服務的治理
- 談談對分散式事務的一點理解和解決方案分散式
- 談一談直播平臺原始碼分散式事務的概念原始碼分散式
- 淺談redux(一)Redux
- MySql(四) InnoDB事務淺析MySql
- 淺談遊戲中的互動敘事遊戲
- 淺談ERP財務管理
- 談談Promise那點事(一)Promise
- 重新學習MySQL資料庫6:淺談MySQL的中事務與鎖MySql資料庫
- 淺談遊戲安全 (一)遊戲
- 淺談 React Hooks(一)ReactHook
- 淺談堆-Heap(一)
- 淺談iOS Crash(一)iOS
- 淺述Oracle分散式事務概念Oracle分散式
- MySQL事務(一)認識事務MySql
- 淺談微服務基建的邏輯微服務
- 深入淺出MYSQL的事務隔離MySql
- 淺談使用者研究那些事(上)定性研究
- 你用對鎖了嗎?淺談 Java “鎖” 事Java
- 淺談浮點數(一)
- Salesforce Javascript(一) Promise 淺談SalesforceJavaScriptPromise