事務 事務操作 事務隔離級別

2022-06-27 17:39:11 字數 3377 閱讀 2408

事務是邏輯上的一組操作,要麼都執行,要麼都不執行。

例如:銀行轉賬,a轉賬1000元給b,這個轉賬就涉及到兩個操作:將a餘額減去1000元,將b餘額加上1000元。但是外一在轉賬的過程中銀行的系統奔潰,導致a只減了,b沒有加,這樣就出錯了。事務就是要保證這兩個操作,要麼都成功,要麼都失敗。

事務必須同時滿足以下4個特性。

(1)原子性:原子性是指乙個事務必須被視為乙個不可分割的最小工作單元,只有事務中所有的資料庫操作都執行成功,才算整個事務執行成功,事務中如果有任何乙個sql語句執行失敗,已經執行成功的sql語句也必須撤銷,資料庫的狀態退回到執行事務前得狀態。

(2)一致性: 在乙個事務執行之前和執行之後資料庫都必須處於一致性狀態。假如資料庫的狀態滿足所有的完整性約束,就說該資料庫是一致的。

一致性是指事務將資料庫從一種狀態轉變為下一種一致的狀態。例如,在表中有乙個欄位為姓名,具有唯一約束,即姓名不能重複,如果乙個事務對姓名進行了修改,使得姓名不唯一了,這就是破壞了事務的一致性要求,如果事務中某個事務失敗了,系統可以自動撤銷事務,返回初始化的狀態。

(3)隔離性:併發訪問資料庫時,乙個使用者的事務不被其他事務所干擾,各併發事務之間資料庫是獨立的;

隔離性還可以稱為併發控制、可序列化、鎖等,當多個使用者併發訪問資料庫時,資料庫為每乙個使用者開啟的事務,不能被其他事務的運算元據所干擾,多個併發事務之間要相互隔離。

(4)永續性:乙個事務被提交之後。它對資料庫中資料的改變是持久的,即使資料庫發生故障也不應該對其有任何影響。

(1)commit 提交:

start transaction

;update account set

money

=money

+100

where name=

『a』;

update account set

money

=money

-100

where name=『b』;

這時只是開啟了事務,語句進行了執行,此時用 select 語句查詢表中的資料,發生了改變,a 變成了1100,b 變成了900。若這時我們斷開資料庫連線,重新登入,再次select查詢表,發現ab這兩個值又重新變回了了1000,1000。這是由於我們的事務實際上只是執行了,並沒有提交,還沒有提交就退出資料庫了,由於事務語句不能自動提交,因此當前的操作就被自動取消了。需要手動使用commit進行提交。

start transaction

;update account set

money

=money

+100

where name=

『a』;

update account set

money

=money

-100

where name=

『b』;

commit;

(2)rollback 回滾:

事務執行完之後,我們沒有退出資料庫連線,但此時想要將事務操作取消,可以使用事務的回滾操作。

rollback;

在典型的應用程式中,多個事務併發執行,操作相同的資料來完成各自的任務,即:多個使用者對同一資料進行操作。可能會導致以下問題:

(1)髒讀(dirty read):乙個事務訪問資料庫對資料進行修改,但是沒有提交,這時另乙個事務也訪問了這個資料,並使用這個資料。因為第乙個事務沒有提交,因此第二個事務讀取的其實是髒資料,並且根據髒資料做的所有的操作都是錯誤的。

乙個事務讀到了其他事務未提交的資料。

(2)丟失修改(lost to modify):兩個事務幾乎同時讀取了同乙個資料,事務1修改了該資料後,事務2也修改了該資料。兩個事務提交後,事務1的結果被事務2的結果覆蓋掉了,即事務1的修改丟失了,因此稱為丟失修改。例如:事務1讀取某錶的資料為a=20,事務2讀取某錶的資料也為a=20,事務1修改a=a-1,事務2修改a=a-2,最終的結果就是a=18,事務1的修改丟失了。

(3)不可重複讀(unrepeatableread):事務1要多次讀取某乙個資料,在事務1還沒結束時,另乙個事務也訪問該資料,並修改該資料。那麼,在事務1兩次讀取資料之間,由於事務2的修改,導致事務1兩次讀取該事物的結果不一樣。這種,在乙個事務多次讀取同一資料,發生了不一樣的情況稱為不可重複讀。

乙個事務在兩次讀取的過程中,有其他的事務對資料進行了修改,導致兩次讀取結果不一樣。

(4)幻讀(phantom read):事務1讀取了幾行資料,事務2插入了幾條資料,當事務1再次查詢的時候,發現多出了幾條原本不存在的記錄,就好像發生了幻覺,所以稱為幻讀。

乙個事務兩次讀取的過程中,有其他的事務對資料進行新增,導致兩次讀取的條數不一樣。

不可重複讀、幻讀的區別:

不可重複讀的重點是修改,幻讀的重點在於新增或者刪除。

例1(同樣的條件, 你讀取過的資料, 再次讀取出來發現值不一樣了 ):事務1中的a先生讀取自己的工資為 1000的操作還沒完成,事務2中的b先生就修改了a的工資為2000,導 致a再讀自己的工資時工資變為 2000;這就是不可重複讀。

例2(同樣的條件, 第1次和第2次讀出來的記錄數不一樣 ):假某工資單表中工資大於3000的有4人,事務1讀取了所有工資大於3000的人,共查到4條記錄,這時事務2 又插入了一條工資大於3000的記錄,事務1再次讀取時查到的記錄就變為了5條,這樣就導致了幻讀。

(1)讀取未提交(read-uncommitted):允許讀取尚未提交的資料變更。隔離級別最低,可能產生髒讀、幻讀、不可重複讀;

(2)讀已提交(read-committed):允許讀取併發事務已提交的資料,沒提交的資料不能讀。能夠阻止髒讀,但是會產生幻讀、不可重複讀;

(3)可重複讀(repeatable-read):對同一資料的多次讀取結果是一致的。除非是自身事務對其進行修改,能夠阻止髒讀、不可重複讀,但會產生幻讀。

(4)可序列化(serializable):最高的隔離級別,完全服從acid的隔離級別。所有事務逐個執行,事務之前完全不產生干擾,能夠阻止所有的併發問題。

補充:mysql innodb 儲存引擎的預設支援的隔離級別是 repeatable-read(可重讀)。

innodb 儲存引擎在 repeatable-read(可重讀)事務隔離級別下使用的是next-key lock 鎖演算法,因此可以避免幻讀的產生,這與其他資料庫系統(如 sql server)是不同的。所以說innodb 儲存引擎的預設支援的隔離級別是 repeatable-read(可重讀) 已經可以完全保證事務的隔離性要求,即達到了 sql標準的serializable(可序列化)隔離級別。因為隔離級別越低,事務請求的鎖越少,所以大部分資料庫系統的隔離級別都是read-committed(讀取提交內容):,但是你要知道的是innodb 儲存引擎預設使用 repeatable-read(可重讀)並不會有任何效能損失。innodb 儲存引擎在 分布式事務 的情況下一般會用到serializable(可序列化)隔離級別。

事務併發 事務隔離級別

併發問題可歸納為以下幾類 a.丟失更新 撤銷乙個事務時,把其他事務已提交的更新資料覆蓋 a和b事務併發執行,a事務執行更新後,提交 b事務在a事務更新後,b事務結束前也做了對該行資料的更新操作,然後回滾,則兩次更新操作都丟失了 b.髒讀 乙個事務讀到另乙個事務未提交的更新資料 a和b事務併發執行,b...

事務併發 事務隔離級別

併發問題可歸納為以下幾類 a.丟失更新 撤銷乙個事務時,把其他事務已提交的更新資料覆蓋 a和 b事務併發執行,a事務執行更新後,提交 b事務在 a事務更新後,b事務結束前也做了對該行資料的更新操作,然後回滾,則兩次更新操作都丟失了 b.髒讀 乙個事務讀到另乙個事務未提交的更新資料 a和 b事務併發執...

事務及事務隔離級別

什麼是事務 事務是訪問資料庫的乙個操作序列,資料庫應用系統通過事務集來完成對資料庫的訪問。事務的正確執行使得資料庫從一種狀態轉換為另一種狀態。事務必須服從iso iec所制定的acid原則。acid是原子性 atomicity 一致性 consistency 隔離性 isolation 永續性 du...