- Mysql事務
- 事務的簡介
- 為什麼需要事務
現在的很多軟體都是多使用者,多程式,多線程的,對同一個表可能同時有很多人在用,為保持資料的一緻性,是以提出了事務的概念。
A 給B 要劃錢,A 的賬戶-1000元, B 的賬戶就要+1000元,這兩個update 語句必須作為一個整體來執行,不然A 扣錢了,B 沒有加錢這種情況很難處理。
- 什麼存儲引擎支援事務
1.檢視資料庫下面是否支援事務(InnoDB支援)?
show engines;
2.檢視mysql目前預設的存儲引擎?
show c'relike '%storage_engine%';
3.檢視某張表的存儲引擎?
show create table 表名 ;
4.對于表的存儲結構的修改?
建立InnoDB 表:Create table .... type=InnoDB; Alter table table_name type=InnoDB;
- 事務的特性
事務應該具有4個屬性:原子性、一緻性、隔離性、持久性。這四個屬性通常稱為ACID特性。
原子性(atomicity)。一個事務是一個不可分割的工作機關,事務中包括的諸操作要麼都做,要麼都不做。
一緻性(consistency)。事務必須是使資料庫從一個一緻性狀态變到另一個一緻性狀态。一緻性與原子性是密切相關的。
隔離性(isolation)。一個事務的執行不能被其他事務幹擾。即一個事務内部的操作及使用的資料對并發的其他事務是隔離的,并發執行的各個事務之間不能互相幹擾。
持久性(durability)。持久性也稱永久性(permanence),指一個事務一旦送出,它對資料庫中資料的改變就應該是永久性的。接下來的其他操作或故障不應該對其有任何影響。
1.1.1.3.1. 原子性(atomicity)
一個事務必須被視為一個不可分割的最小單元,整個事務中的所有操作要麼全部送出成功,要麼全部失敗,對于一個事務來說,不可能隻執行其中的一部分操作
比如: 老婆大人給Deer老師發生活費
1.老婆大人工資卡扣除500元
2.Deer老師工資卡增加500
不能出現工資卡扣除500元,但Deer老師工資卡沒有增加500元的情況
要麼全部成功,要麼全部失敗
1.1.1.3.2. 一緻性(consistency)
一緻性是指事務将資料庫從一種一緻性轉換到另外一種一緻性狀态,在事務開始之前和事務結束之後資料庫中資料的完整性沒有被破壞
比如:
1.老婆大人工資卡扣除500元
2.Deer老師工資卡增加500
2.Deer老師工資卡增加1000
不能因為任何原因,導緻Deer老師收到兩次錢
1.1.1.3.3. 持久性(durability)
一旦事務送出,則其所做的修改就會永久儲存到資料庫中。此時即使系統崩潰,已經送出的修改資料也不會丢失
1.1.1.3.4. 隔離性(isolation)
隔離性要求一個事務對資料庫中資料的修改,在未送出完成前對于其他事務是不可見的
- 事務隔離級别
mysql預設的事務隔離級别為repeatable-read
show variables like '%tx_isolation%';

- 未送出讀(READ UNCOMMITED)髒讀
set SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
測試:
啟動兩個session
一個session中
start TRANSACTION
update account set balance = balance -50 where id = 1
另外一個session中查詢
select * from account
回到第一個session中 復原事務
ROLLBACK
在第二個session種
update account set balance = balance -50 where id = 1
查詢結果還是 400
第二個session以為結果是350,但前面的400資料為髒讀資料,導緻最後的結果和意料中的結果并不一緻。
- 已送出讀 (READ COMMITED)不可重複讀
測試
show variables like '%tx_isolation%';
set SESSION TRANSACTION ISOLATION LEVEL read committed;
一個session中
start TRANSACTION
update account set balance = balance -50 where id = 1
另外一個session中查詢 (資料并沒改變)
select * from account
回到第一個session中 復原事務
commit
在第二個session種
select * from account (資料已經改變)
- 可重複讀(REPEATABLE READ)
測試
show variables like '%tx_isolation%';
set SESSION TRANSACTION ISOLATION LEVEL repeatable read;
一個session中
start TRANSACTION
update account set balance = balance -50 where id = 1
另外一個session中查詢 (資料并沒改變)
select * from account
回到第一個session中 復原事務
commit
在第二個session種
select * from account (資料并未改變)
- 可串行化(SERIALIZABLE)
account 表有3條記錄,業務規定,最多允許4條記錄。
1.開啟一個事務
begin
select * from account 發現3條記錄
2.開啟另外一個事務
begin
select * from account 發現3條記錄 也是3條記錄
insert into account VALUES(4,'deer',500)
查詢 4條記錄
select * from account
3.回到第一個session
insert into account VALUES(5,'james',500)
select * from account 4條記錄
4.session1 與 session2 都送出事務
- set SESSION TRANSACTION ISOLATION LEVEL serializable; 重新上面的測試發現插入報錯
- 總結
事務隔離級别為可重複讀時,如果有索引(包括主鍵索引)的時候,以索引列為條件更新資料,會存在間隙鎖間、行鎖、頁鎖的問題,進而鎖住一些行;如果沒有索引,更新資料時會鎖住整張表
事務隔離級别為串行化時,讀寫資料都會鎖住整張表
隔離級别越高,越能保證資料的完整性和一緻性,但是對并發性能的影響也越大,對于多數應用程式,可以優先考慮把資料庫系統的隔離級别設為Read Committed,它能夠避免髒讀取,而且具有較好的并發性能。
- 事務文法
- 開啟事務
1、begin
2、START TRANSACTION(推薦)
3、begin work
- 事務復原
rollback
- 事務送出
commit
- 還原點
savepoint
show variables like '%autocommit%'; 自動送出事務是開啟的
set autocommit=0;
insert into testdemo values(5,5,5);
savepoint s1;
insert into testdemo values(6,6,6);
savepoint s2;
insert into testdemo values(7,7,7);
savepoint s3;
select * from testdemo