1. 事務(wù)的基本介紹
-
概念:
如果一個(gè)包含多個(gè)步驟的業(yè)務(wù)操作,這些操作要么同時(shí)成功企垦,要么同時(shí)失敗涎永,否則就會(huì)出現(xiàn)數(shù)據(jù)錯(cuò)亂的情況。事務(wù)就是用來管理這些業(yè)務(wù)操作一死,保證能夠同時(shí)執(zhí)行成功或失敗肛度。操作:
1. 開啟事務(wù): start transaction;
2. 回滾:rollback;
3. 提交:commit;
4.保存節(jié)點(diǎn):savepoint 節(jié)點(diǎn)名稱
5.回滾節(jié)點(diǎn):rollback to 節(jié)點(diǎn)名稱-
例子:
CREATE TABLE account ( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(10), balance DOUBLE ); -- 添加數(shù)據(jù) INSERT INTO account (NAME, balance) VALUES ('zhangsan', 1000), ('lisi', 1000); SELECT * FROM account; UPDATE account SET balance = 1000; -- 張三給李四轉(zhuǎn)賬 500 元 -- 0. 開啟事務(wù) START TRANSACTION; -- 1. 張三賬戶 -500 UPDATE account SET balance = balance - 500 WHERE NAME = 'zhangsan'; -- 2. 李四賬戶 +500 -- 出錯(cuò)了... UPDATE account SET balance = balance + 500 WHERE NAME = 'lisi'; -- 發(fā)現(xiàn)執(zhí)行沒有問題,提交事務(wù) COMMIT; -- 發(fā)現(xiàn)出問題了摘符,回滾事務(wù) ROLLBACK;
-
MySQL數(shù)據(jù)庫中事務(wù)默認(rèn)自動(dòng)提交
- 事務(wù)提交的兩種方式:
- 自動(dòng)提交:
- mysql就是自動(dòng)提交的
- 一條DML(增刪改)語句會(huì)自動(dòng)提交一次事務(wù)贤斜。
- 手動(dòng)提交:
- Oracle 數(shù)據(jù)庫默認(rèn)是手動(dòng)提交事務(wù)
- 需要先開啟事務(wù),再提交
- 自動(dòng)提交:
- 修改事務(wù)的默認(rèn)提交方式:
- 查看事務(wù)的默認(rèn)提交方式:SELECT @@autocommit;
-- 1 代表自動(dòng)提交 0 代表手動(dòng)提交 - 修改默認(rèn)提交方式: set @@autocommit = 0;
- 查看事務(wù)的默認(rèn)提交方式:SELECT @@autocommit;
- 事務(wù)提交的兩種方式:
-
2. 事務(wù)的四大特征:
1. 原子性:是不可分割的最小操作單位逛裤,要么同時(shí)成功瘩绒,要么同時(shí)失敗。
2. 持久性:當(dāng)事務(wù)提交或回滾后带族,數(shù)據(jù)庫會(huì)持久化的保存數(shù)據(jù)锁荔。
3. 隔離性:多個(gè)事務(wù)之間。相互獨(dú)立蝙砌。
4. 一致性:事務(wù)操作前后阳堕,數(shù)據(jù)總量不變
3. 事務(wù)的隔離級(jí)別
概念:
多個(gè)事務(wù)之間是隔離的,相互獨(dú)立的择克。但是如果多個(gè)事務(wù)操作同一批數(shù)據(jù)恬总,則會(huì)引發(fā)一些問題,設(shè)置不同的隔離級(jí)別就可以解決這些問題肚邢。存在問題:
1. 臟讀:一個(gè)事務(wù)壹堰,讀取到另一個(gè)事務(wù)中沒有提交的數(shù)據(jù)
2. 不可重復(fù)讀(虛讀):在同一個(gè)事務(wù)中拭卿,兩次讀取到的數(shù)據(jù)不一樣。
3. 幻讀:同一個(gè)事務(wù)內(nèi)多次查詢返回的結(jié)果集不一樣贱纠。比如同一個(gè)事務(wù) A 第一次查詢時(shí)候有 n 條記錄峻厚,但是第二次同等條件下查詢卻有 n+1 條記錄,這就好像產(chǎn)生了幻覺谆焊。-
隔離級(jí)別:
1. read uncommitted:讀未提交(最低隔離級(jí)別惠桃,事務(wù)未提交前,就可以被其他事務(wù)讀认绞浴)
* 產(chǎn)生的問題:臟讀辜王、不可重復(fù)讀、幻讀
2. read committed:讀已提交 (一個(gè)事務(wù)提交后才能被其他事務(wù)讀取到)
* 產(chǎn)生的問題:不可重復(fù)讀剃执、幻讀
3. repeatable read:可重復(fù)讀 (MySQL默認(rèn)級(jí)別誓禁,保證多次讀取一個(gè)數(shù)據(jù)時(shí),其值都和事務(wù)開始時(shí)的內(nèi)容一致肾档,禁止讀取到別的事務(wù)未提交的數(shù)據(jù))
* 產(chǎn)生的問題:幻讀
4. serializable:序列化(代價(jià)最高最可靠的隔離級(jí)別)
* 可以解決所有的問題- 注意:隔離級(jí)別從小到大安全性越來越高摹恰,但是效率越來越低
MySQL默認(rèn)事務(wù)隔離級(jí)別是repeatable read,一般情況下沒有特殊要求怒见,沒有必要修改俗慈。因?yàn)樵摷?jí)別可以滿足絕大部分項(xiàng)目需求。
- 注意:隔離級(jí)別從小到大安全性越來越高摹恰,但是效率越來越低
-
實(shí)際操作
查詢當(dāng)前會(huì)話隔離級(jí)別:
select @@tx_isolation;
查詢系統(tǒng)當(dāng)前隔離級(jí)別:
select @@global.tx_isolation;
設(shè)置當(dāng)前會(huì)話隔離級(jí)別:
set session transaction isolation level repeatable read(級(jí)別字符串);
設(shè)置系統(tǒng)當(dāng)前隔離級(jí)別:
set global transaction isolation level repeatable read;
全局修改遣耍,修改MySQL. ini 配置文件在文件的最后添加:
transaction-isolation = REPEATABLE-READ
可用的配置值:READ-UNCOMMITTED闺阱、READ-COMMITTED、REPEATABLE-READ舵变、SERIALIZABLE酣溃。* 演示: set global transaction isolation level read uncommitted; start transaction; -- 轉(zhuǎn)賬操作 update account set balance = balance - 500 where id = 1; update account set balance = balance + 500 where id = 2;