事務簡介
事務的作用
事務的作用是將一系列操作作為乙個整體,一但其**現問題,會回滾到事務的開始狀態。即事務維護了資料的完整性和一致性。
事務的四個特性(acid)
原子性:事務的操作是原子不可分割的。 一致性:事務的運算元據保證一致性,不存在一部分改變一部分不改變。 隔離性:隔離性是當多個使用者併發訪問資料庫時,比如操作同一張表時,資料庫為每乙個使用者開啟的事務,不能被其他事務的操作所干擾,多個併發事務之間要相互隔離。 永續性(durability):一旦事務完成,無論發生什麼系統錯誤,它的結果都不應該受到影響。
隔離級別導致的問題
如果不考慮隔離性,事務會出現以下問題。
髒讀髒讀又稱無效資料的讀出,是指在資料庫訪問中,事務t1將某一值修改,然後事務t2讀取該值,此後t1因為某種原因撤銷對該值的修改,這就導致了t2所讀取到的資料是無效的。髒讀是讀到了另乙個事務的中為commit的髒資料,所以稱為髒讀。
重現過程,將資料庫隔離界別設為read-committed,開啟兩個資料庫連線,連線a去開啟事務,insert 乙個調資料,連線b查詢出這條資料,連線a提交rollback,連線b再查詢。
connect_a > begin;
connect_a > insert into app(app_code,app_name,customer_code,latest_version_code,client_version,create_time) values ('1','1','003','1.0','1.0',now());
connect_b > select app_name from app;
connect_a > rollback;
connect_b > select app_name from app;
不可重複讀
不可重複讀是指乙個執行緒中的事務讀取到了另外乙個執行緒中提交的update的資料。
如事務t1查詢某人員資料,這時事務t2修改了該人員資料,t1再次查詢該人員資料,發現該事務中兩次查詢的資料不一致。
重現過程,將資料庫隔離設為read-uncommitted,開啟兩個資料庫連線,連線a開啟事務,查詢表資訊,連線b修改一條資料,連線a再查表記錄,導致連線a兩次查詢資料不一致。
connect_a > begin;
connect_a > select app_name from app;
connect_b > update app set app_name='2' where app_code='1';
connect_a > select app_name from app;
connect_a > commit;
虛讀(幻讀)
虛讀是指乙個執行緒中的事務讀取到了另外乙個執行緒中提交的insert的資料。
如事務t1查詢人物資料有6條,事務t2插入1條資料,事務t1再查詢人物資料就為7條了。
重現過程,將資料庫隔離級別設為repeatable-read,開啟兩個資料庫連線,連線a開啟事務,查詢表記錄,連線b插入一條表記錄,連線a再次查詢表記錄。
connect_a > begin;
connect_a > select app_name from app;
connect_b > update app set app_name='2' where app_code='1';
connect_a > select app_name from app;
connect_a > commit;
不可重複讀和虛讀都是事務在執行過程中,有其他事務修改了資料,不過不可重複讀是修改,而虛讀是新增或刪除。
事務提交
在事務中,使用rollback或commit作為事務結束的標誌,如果事務未提交就關閉了,需要手動查詢出事務程序,並殺掉
sql > show processlist;
sql > kill xx;
事務的隔離級別
read uncommitted 讀未提交,就是能讀到未提交的資料 read committed 讀已提交,讀到已提交的資料 repeatable read 可重複讀,乙個事務中,重複讀的資料都是一樣的,不管是否有別的事務修改資料 serializable 序列化,每次讀都獲得整個表的鎖,讀寫相互堵塞。稱為悲觀鎖。
下面是隔離級別與資料問題的關係
讀未提交(read uncommitted) 讀已提交(read committed) 可重複讀(repeatable read) 序列化(serializable)
髒讀 會發生 不會發生 不會發生 不會發生
不可重複讀 會發生 會發生 不會發生 不會發生
虛讀(幻讀) 會發生 會發生 會發生 不會發生
mysql支援以上四中隔離級別,預設隔離級別是repeatable read;oracle只支援序列化(serializable)、讀已提交(read committed),預設是讀已提交(read committed)級別。
mysql檢視當前隔離級別:
select @@tx_isolation;
mysql設定隔離級別語句
set [glogal | session] transactionisolation level 隔離級別名稱;
或set tx_isolation='隔離級別名稱';
如set tx_isolation='read-committed'
鎖資料庫的鎖有x鎖(排他鎖),s鎖(共享鎖)。每個資料庫的查詢執行前,都必須要拿到鎖才能執行。當乙個連線拿到x鎖(排他鎖)時,其他的連線都拿不到鎖了,要等這個連線的x鎖解鎖。如果乙個連線拿到了s鎖,其他資料庫連線還是能拿到s鎖的,互不干擾。
鎖的粒度型別有record lock(行鎖),gap lock(間隙鎖)。行鎖是按照索引鎖住這個索引對應的資料。間隙鎖是鎖住這個索引以上的或以下的鎖,就是範圍鎖。
**封鎖協議
第一級在修改時修改資料開啟x鎖,事務提交關閉。事務唯讀不修改是不用加鎖的。可以保證提交資料丟失的情況。可能會出現髒讀,不可重複讀,虛讀。
第二級在事務中,第一級封鎖協議加上查詢時對相應的資料新增s鎖,查詢結束關閉。這樣可以保證事務讀取的資料都是事務已經提交的,解決髒讀問題
第**在事務中,第一級封鎖協議加上查詢對應資料新增s鎖,s鎖直到事務提交。可以解決可重複的問題。
mysql innodb幻讀
mysql通過(read view),mvcc實現避免幻讀。即讀的資料不是最新的資料,而是之前的快照。
鎖的策略 — 事務隔離級別
讀未提交(read-uncommitted)
查詢使用s鎖,修改時對應行資料使用x鎖,修改結束釋放x鎖。
讀已提交(read-committed)
查詢使用s鎖,查詢結束,釋放s鎖。修改時,對應行資料使用x鎖,直到事務結束,釋放x鎖。
可重複讀(repeatable-read)
使用mvvc。
序列化(serializable)
該隔離級別會在讀取的每一行資料上都加上鎖,退化為基於鎖的併發控制,即lbcc。使用的間隙鎖,所以能解決幻讀。
事務處理(二) 資料庫事務
事務的作用是將一系列操作作為乙個整體,一但其中出現問題,會回滾到事務的開始狀態。即事務維護了資料的完整性和一致性。如果不考慮隔離性,事務會出現以下問題。髒讀又稱無效資料的讀出,是指在資料庫訪問中,事務t1將某一值修改,然後事務t2讀取該值,此後t1因為某種原因撤銷對該值的修改,這就導致了t2所讀取到...
資料庫的事務處理
事務是這樣一種機制,它確保多個sql語句被當作單個工作單 元來處理。事務具有以下的作用 事務是完整性的單位,乙個事務的執行是把資料庫從乙個一 致的狀態轉換成另乙個一致的狀態。因此,如果事務孤立執行時 是正確的,但如果多個事務併發交錯地執行,就可能相互干擾,造成資料庫狀態的不一致。在多使用者環境中,資...
資料庫 9 1 事務處理
事務就是將一組sql語句放在同一批次內去執行 如果乙個sql語句出錯,則該批次內的所有sql都將被取消執行 mysql事務處理不支援innodb和bdb資料表型別 事務的acid原則 原子性 atomic 一致性 consist 隔離性 isolated 永續性 durable mysql的事務實現...