一. 事務簡介
事務是一組操作的集合,它是一個不可分隔的作業單位,事務會把所有的操作作為一個整體一起向系統提交或撤銷操作請求,即這些操作要么同時成功,要么同時失敗,
就比如:張三給李四轉賬1000塊錢,張三銀行賬戶的錢減少了1000,而李四銀行賬戶的錢要增加1000,這一組操作就必須在一個事務的范圍內,要么都成功,要么都失敗,
正常情況:轉賬這個操作,需要分為以下這么三步來完成,三步完成之后,張三減少1000,而李四增加1000,轉賬成功:
例外情況:轉賬這個操作,也是分為以下這么三步來完成,在執行第三步時報錯了,這樣就導致張三減少1000塊錢,而李四的金額沒變,這樣就造成了資料的不一致,就出現問題了,
為了解決上述的問題,就需要通過資料的事務來完成,我們只需要在業務邏輯執行之前開啟事務,執行完畢后提交事務,如果執行程序中報錯,則回滾事務,把資料恢復到事務開始之前的狀態,
注:默認MySQL的事務時自動提交的,也就是說,當執行完一條DML陳述句時,MySQL會立即隱式的提交事務,
二. 事務操作
資料準備:
drop table if exists account;
create table account(
id int primary key AUTO_INCREMENT comment 'ID',
name varchar(10) comment '姓名',
money double(10,2) comment '余額'
) comment '賬戶表';
insert into account(name, money) VALUES ('張三',2000), ('李四',2000);
1. 未控制事務
(1). 測驗正常情況
-- 1. 查詢張三余額
select * from account where name = '張三';
-- 2. 張三的余額減少1000
update account set money = money - 1000 where name = '張三';
-- 3. 李四的余額增加1000
update account set money = money + 1000 where name = '李四';
測驗完畢之后檢查資料的狀態,可以看出資料操作前后是一致的,
(2). 測驗例外情況
-- 1. 查詢張三余額
select * from account where name = '張三';
-- 2. 張三的余額減少1000
update account set money = money - 1000 where name = '張三';
出錯了....
-- 3. 李四的余額增加1000
update account set money = money + 1000 where name = '李四';
我們把資料都恢復到2000,然后再次一次性執行上述的SQL陳述句(出錯了... 這句話不符合SQL語法,執行就會報錯),檢查最終的資料情況,發現資料在操作前后不一致了,
2. 控制事務一
(1). 查看/設定事務提交方式
SELECT @@autocommit;
SET @@autocommit = 0;
(2). 提交事務
COMMIT;
(3). 回滾事務
ROLLBACK;
注:上述的這種方式,我們是修改了事務的自動提交行為,把默認的自動提交修改為了手動提交,此時我們執行的DML陳述句都不會提交,需要手動的執行commit進行提交,
3. 控制事務二
(1).開啟事務
START TRANSACTION 或 BEGIN ;
(2).提交事務
COMMIT;
(3).回滾事務
ROLLBACK;
轉賬案例:
-- 開啟事務
start transaction;
-- 1. 查詢張三余額
select * from account where name = '張三';
-- 2. 張三的余額減少1000
update account set money = money - 1000 where name = '張三';
-- 3. 李四的余額增加1000
update account set money = money + 1000 where name = '李四';
-- 如果正常執行完畢, 則提交事務
commit;
-- 如果執行程序中報錯, 則回滾事務
-- rollback;
三. 事務四大特性
-
原子性(Atomicity):事務是不可分隔的最小操作單元,要么全部成功,要么全部失敗,
-
一致性(Consistency):事務完成時,必須使所有的資料都保持一致,
-
隔離性(Isolation):資料庫系統提供的隔離機制,保證事務在不受外部并發操作影響的獨立環境下運行,
-
持久性(Durability):事務一旦提交或回滾,它對資料庫中的資料的改變就是永久的,
上述就是事務的四大特性,簡稱ACID,
四. 并發事務問題
1. 臟讀:一個事務讀到另一個事務還沒有提交的資料
2. 不可重復讀:一個事務先后讀取同一條記錄,但兩次讀取的資料不同,稱之為不可重復讀
3. 幻讀:一個事務按照條件查詢資料時,沒有對應的資料行,但是在插入資料時,又發現這行資料已經存在,好像出現了”幻影”,
五. 事務隔離級別
為了解決并發事務所引發的問題,在資料庫中引入了事務隔離級別,主要有以下幾種:
隔離級別 | 臟讀(是否解決) | 不可重復讀(是否解決) | 幻讀(是否解決) |
---|---|---|---|
讀未提交(Read uncommitted) | 未解決 | 未解決 | 未解決 |
讀已提交(Read committed) | 解決 | 未解決 | 未解決 |
可重復讀(Repeatable Read)(默認) | 解決 | 解決 | 未解決 |
串行化(Serializable) | 解決 | 解決 | 解決 |
1. 查詢事務隔離級別
SELECT @@TRANSACTION_ISOLATION;
2. 設定事務隔離級別
SET [ SESSION | GLOBAL ] TRANSACTION ISOLATION LEVEL
{ READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
SESSION:session表示當前視窗的隔離級別,
GLOBAL:global表示全域的隔離級別
注:事務隔離級別越高,資料越安全,但是性能越低,
更多mysql學習請關注微信公眾號”云哥技術yun3k”,回復”mysql學習”,免費領取mysql全套學習資料,
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/556567.html
標籤:MySQL
上一篇:Mysql基礎篇(三)之多表查詢
下一篇:返回列表