MySQL系列之十 MySQL事務(wù)隔離實(shí)現(xiàn)并發(fā)控制
一、并發(fā)訪問(wèn)控制
實(shí)現(xiàn)的并發(fā)訪問(wèn)的控制技術(shù)是基于鎖;
鎖分為表級(jí)鎖和行級(jí)鎖,MyISAM存儲(chǔ)引擎不支持行級(jí)鎖;InnoDB支持表級(jí)鎖和行級(jí)鎖;
鎖的分類有讀鎖和寫鎖,讀鎖也被稱為共享鎖,加讀鎖的時(shí)候其他的人可以讀;寫鎖也稱為獨(dú)占鎖或排它鎖,一個(gè)寫鎖會(huì)阻塞其他讀操作和寫操作;
鎖還分為隱式鎖和顯式鎖,隱式鎖由存儲(chǔ)引擎自行管理,顯式鎖是用戶手動(dòng)添加鎖;
鎖策略:在鎖粒度及數(shù)據(jù)安全性尋求的平衡機(jī)制。
顯式鎖的使用方法:LOCK TABLES tbl_name READ|WRITE
MariaDB [school]> LOCK TABLES students READ; #加讀鎖
MariaDB [school]> UNLOCK TABLES; #解鎖
讀鎖:任何人都不可寫
寫鎖:自己可以讀寫,但是其他人不可讀寫
FLUSH TABLES tb_name :關(guān)閉正在打開(kāi)的表(清除查詢緩存),通常在備份前加全局讀鎖
SELECT clause [FOR UPDATE | LOCK IN SHARE MODE] 查詢時(shí)加寫或讀鎖
二、事務(wù)Transactions
一組原子性的SQL語(yǔ)句,或一個(gè)獨(dú)立工作單元
1、事務(wù)遵循ACID原則:
- A:atomicity原子性;整個(gè)事務(wù)中的所有操作要么全部成功執(zhí)行,要么全部失敗后回滾
- C:consistency一致性;數(shù)據(jù)庫(kù)總是從一個(gè)一致性狀態(tài)轉(zhuǎn)換為另一個(gè)一致性狀態(tài)
- I:Isolation隔離性;一個(gè)事務(wù)所做出的操作在提交之前,是不能為其它事務(wù)所見(jiàn);隔離有多種隔離級(jí)別,實(shí)現(xiàn)并發(fā)
- D:durability持久性;一旦事務(wù)提交,其所做的修改會(huì)永久保存于數(shù)據(jù)庫(kù)中
2、事務(wù)的生命周期
顯式事務(wù):明確的規(guī)定事務(wù)的開(kāi)始
隱式事務(wù):默認(rèn)為隱式事務(wù),每執(zhí)行完一句語(yǔ)句后直接提交
autocommit = {OFF|ON} 開(kāi)啟或關(guān)閉自動(dòng)提交,建議使用顯式請(qǐng)求和提交事務(wù),而不要使用“自動(dòng)提交”功能
啟動(dòng)事務(wù):START TRANSACTION;
插入標(biāo)簽:ROLLBACK TO ##;
撤銷回指定標(biāo)簽:ROLLBACK TO ##;
全部撤銷:ROLLBACK;
提交事務(wù):COMMIT;
刪除標(biāo)簽:RELEASE SAVEPOINT;
MariaDB [school]> START TRANSACTION; #明確指明啟動(dòng)一個(gè)事務(wù) MariaDB [school]> INSERT students(StuID,Name,Age,Gender) VALUES (26,'Tom',22,'M'); #添加一條記錄 MariaDB [school]> SAVEPOINT sp26; #插入一個(gè)標(biāo)簽 MariaDB [school]> INSERT students(StuID,Name,Age,Gender) VALUES (27,'Maria',12,'F'); #再加入一條記錄 MariaDB [school]> SELECT * FROM students WHERE stuid IN (26,27); #查看一下,可以看到剛剛插入的數(shù)據(jù) +-------+-------+-----+--------+---------+-----------+ | StuID | Name | Age | Gender | ClassID | TeacherID | +-------+-------+-----+--------+---------+-----------+ | 26 | Tom | 22 | M | NULL | NULL | | 27 | Maria | 12 | F | NULL | NULL | +-------+-------+-----+--------+---------+-----------+ MariaDB [school]> ROLLBACK TO sp26; #撤銷到sp26標(biāo)簽之前的狀態(tài) MariaDB [school]> SELECT * FROM students WHERE stuid IN (26,27); #查看一下,剛剛maria的信息被撤回了 +-------+------+-----+--------+---------+-----------+ | StuID | Name | Age | Gender | ClassID | TeacherID | +-------+------+-----+--------+---------+-----------+ | 26 | Tom | 22 | M | NULL | NULL | +-------+------+-----+--------+---------+-----------+ MariaDB [school]> COMMIT; #提交事務(wù) MariaDB [school]> SELECT * FROM students WHERE stuid IN (26,27); #最終的數(shù)據(jù) +-------+------+-----+--------+---------+-----------+ | StuID | Name | Age | Gender | ClassID | TeacherID | +-------+------+-----+--------+---------+-----------+ | 26 | Tom | 22 | M | NULL | NULL | +-------+------+-----+--------+---------+-----------+
3、事務(wù)的隔離級(jí)別
- READ UNCOMMITTED 其他事務(wù)可以看到未提交的臟數(shù)據(jù),產(chǎn)生臟讀
- READ COMMITTED 提交后其他事務(wù)可以看到修改后的數(shù)據(jù),每次讀取的數(shù)據(jù)可能不一致,不可重復(fù)讀
- REPEATABLE READ 可重復(fù)讀,每次看到的數(shù)據(jù)都一致,數(shù)據(jù)被修改后看不到最新數(shù)據(jù),會(huì)產(chǎn)生幻讀(默認(rèn)設(shè)置)
- SETIALIZABILE 未提交的讀事務(wù)阻塞修改事務(wù),串行執(zhí)行,并發(fā)性差
MVCC: 多版本并發(fā)控制,和事務(wù)級(jí)別相關(guān)
修改事務(wù)隔離級(jí)別:服務(wù)器變量tx_isolation指定,默認(rèn)為REPEATABLE-READ,可在GLOBAL和SESSION級(jí)進(jìn)行設(shè)置
tx_isolation
- Description: The transaction isolation level. See also SET TRANSACTION ISOLATION LEVEL.
- Commandline:
--transaction-isolation=name
- Scope: Global, Session
- Dynamic: Yes
- Type: enumeration
- Default Value:
REPEATABLE-READ
- Valid Values:
READ-UNCOMMITTED
,READ-COMMITTED
,REPEATABLE-READ
,SERIALIZABLE
MariaDB [school]> SELECT @@tx_isolation; #默認(rèn)為可重復(fù)讀級(jí)別 +-----------------+ | @@tx_isolation | +-----------------+ | REPEATABLE-READ | +-----------------+ MariaDB [school]> SET tx_isolation='READ-UNCOMMITTED'; MariaDB [school]> set tx_isolation='READ-COMMITTED'; MariaDB [school]> set tx_isolation='REPEATABLE-READ'; MariaDB [school]> set tx_isolation='SERIALIZABLE';
4、死鎖
兩個(gè)或多個(gè)事務(wù)在同一資源相互占用,并請(qǐng)求鎖定對(duì)方占用的資源的狀態(tài)會(huì)發(fā)生死鎖
在A事務(wù)修改t1表的第3行,B事務(wù)修改t2表的第2行時(shí);這時(shí)A事務(wù)去修改t2表的第2行,這時(shí)就把A事務(wù)阻塞了,然后B事務(wù)有剛剛好去修改t1表的第3行,這時(shí)B事務(wù)也被阻塞了,這時(shí)就產(chǎn)生了死鎖。
倆個(gè)事務(wù)同時(shí)去更改對(duì)方的修改的表,互相阻塞;系統(tǒng)會(huì)發(fā)現(xiàn)死鎖,會(huì)自動(dòng)犧牲一個(gè)代價(jià)小的事務(wù)來(lái)解開(kāi)死鎖。
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
查看進(jìn)程列表:MariaDB [school]> SHOW PROCESSLIST;
殺死進(jìn)程:MariaDB [school]> KILL 5;
到此這篇關(guān)于MySQL系列之十 MySQL事務(wù)隔離實(shí)現(xiàn)并發(fā)控制的文章就介紹到這了,更多相關(guān)mysql并發(fā)控制內(nèi)容請(qǐng)搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!
到此這篇關(guān)于MySQL系列之十 MySQL事務(wù)隔離實(shí)現(xiàn)并發(fā)控制的文章就介紹到這了,更多相關(guān)mysql并發(fā)控制內(nèi)容請(qǐng)搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!
版權(quán)聲明:本站文章來(lái)源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請(qǐng)保持原文完整并注明來(lái)源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來(lái)源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來(lái),僅供學(xué)習(xí)參考,不代表本站立場(chǎng),如有內(nèi)容涉嫌侵權(quán),請(qǐng)聯(lián)系alex-e#qq.com處理。