1、事務定義
1)用於大數據
MySQL 事務用於處理操作量大,複雜度高的數據。比如,在人員管理系統中,刪除了一個人員的信息,你既需要刪除人員的基本資料,也要刪除和該人員相關的信息,如註冊號碼、信箱,文章等等,這樣,這些數據庫操作語句就構成一個事務!
2)能保障安全
一個最小的不可再分的工作單元,通常一個事務對應一個完整的業務。如:手機轉賬,該業務就是一個最小的工作單元,它涉及了你各方面的信息和轉賬對方的信息,這是一種鏈接式的。你的賬戶錢少了,對方賬戶錢多了,兩者必須都成功了,這項操作纔算真正結束,如果進行到一半出問題了,你的錢是不會少的,因爲這一個事務還沒有結束。
3)事務前提
- 在 MySQL 中只有使用了 Innodb 數據庫引擎的數據庫或表才支持事務。
- 事務處理可以用來維護數據庫的完整性,保證成批的 SQL 語句要麼全部執行,要麼全部不執行。
- 事務用來管理 insert,update,delete 語句
綜上所述,事務指邏輯上的一組操作,組成這組操作的各個單元,要不全部成功,要不全部不成功。
2、事務的四大特徵
1)原子性: 一個事務中的所有操作,要麼都發生,要麼都不發生,不會結束在中間某個環節。
2)一致性: 在事務開始之前和事務結束以後,數據庫的完整性沒有被破壞。無論事務是否執行成功,事務結束後的數據庫中的數據也應該是符合完整性約束的。
3)隔離性: 多個用戶併發訪問數據庫時,一個用戶的事務不能被其它用戶的事務所幹擾。
4)持久性: 一個事務一旦被提交,就代表一個事務的結束,它對數據的修改就是永久的,即便系統故障也不會丟失。
注意:
在 MySQL 命令行的默認設置下,事務都是自動提交的,即執行 SQL 語句後就會馬上執行 COMMIT
操作。因此要顯式地開啓一個事務務須使用命令 BEGIN 或 START TRANSACTION,或者執行命令 SET
AUTOCOMMIT=0,用來禁止使用當前會話的自動提交。
3、事務操作
- 開啓事務: Start Transaction
- 事務結束: End Transaction
- 提交事務: Commit Transaction
- 回滾事務: Rollback Transaction
即撤銷指定的sql語句(只能回退insert delete update語句),回滾到上一次commit的位置 - 設保留點: Savepoint identifier
事務處理中設置的臨時佔位符 你可以對它發佈回退(與整個事務回退不同) - 刪保留點: Release Savepoint identifier
- 改提交模式:
SET AUTOCOMMIT=0 禁止自動提交
SET AUTOCOMMIT=1 開啓自動提交
4、savepoint練習
1)首先創建帶有innodb引擎的數據表
--創建使用事務引擎的數據表(設置engine爲innodb)
create table emp(id INT PRIMARY KEY auto_increment,name VARCHAR(20)) engine=innodb;
--插入數據
INSERT INTO emp(name) VALUE ("ViewIN"),
("Zoro"),
("ZaHuw");
2)開啓事務,並再插入一個數據
--開啓事務
start transaction;
--再次插入數據
insert into emp (name) values ('ZaHuw_tow');
--此時查看,並不會有變化
select * from emp;
--提交之後纔會有變化
commit;
然後查看錶的內容,會發現並沒有新的數據進入,因爲我們還沒有提交事務。當commit之後,表纔會變化。
3)設置保留點
--設置保留點
start transaction;
insert into emp (name) values('OK');
--設置一個名爲insert_OK的保留點
savepoint insert_OK;
select * from emp;
4)進行刪除操作,並再設一個保留點
--進行刪除操作
delete from emp where id=5;
--再次設置一個名爲delete1的保留點
savepoint delete1;
select * from emp;
5)再刪一次,並設保留點
--再刪一次,並設保留點
delete from emp where id=3;
savepoint delete2;
select * from emp;
此時已經設置了三個保留點,並且三個操作其實都有效果,當我們使用回滾事務時,就可以返回到對應的保留點處
6)回滾保留點
--回滾保留點
rollback to delete1;
select * from emp;
這樣我們就回到了delete1保留點,也就是隻刪除了id=5的數據
5、事務在Python中的使用
import pymysql
# 連接MySQL
conn = pymysql.connect(host='192.168.43.247', port=3306, user='root', passwd='', db='sqlpwd')
# 創建遊標
cursor = conn.cursor()
# 創建事務數據表
# CR= "create table account2(id INT PRIMARY KEY auto_increment,name VARCHAR(20)) engine=innodb"
# cursor.execute(CR)
# 插入數據
# into_name= "INSERT INTO account2 (name) VALUE ("ViewIN"),("Zoro"),("ZaHuw")"
# cursor.execute(into_name)
try:
# 插入數據
insertSQL0= "INSERT INTO account2 (name,balance) VALUES ('Zero',4000)"
insertSQL1= "UPDATE account2 set balance=balance-1000 WHERE name='One'"
insertSQL2= "UPDATE account2 set balance=balance+1000 WHERE name='Tow'"
cursor = conn.cursor()
cursor.execute(insertSQL0)
conn.commit()
cursor.execute(insertSQL1)
raise Exception
cursor.execute(insertSQL2)
cursor.close()
conn.commit()
except Exception as e:
conn.rollback()
conn.commit()
cursor.close()
conn.close()
6、隔離級別
1)四種隔離級別
- Serializable:可避免髒讀、不可重複讀、虛讀情況的發生。(串行化)
- Repeatable read:可避免髒讀、不可重複讀情況的發生,不可以避免虛讀(可重複讀)
- Read committed:可避免髒讀情況發生(讀已提交)
- Read uncommitted:最低級別,以上情況均無法保證。(讀未提交)
2)均衡對照
安全性考慮:Serializable > Repeatable read > Read committed > Read uncommitted
數據庫效率:Read uncommitted > Read committed > Repeatable read > Serializable
一般情況下,我們會使用Repeatable read、Read committed mysql數據庫默認的數據庫隔離級別Repeatable read
3)mysql中設置數據庫的隔離級別語句:
set [global/session] transaction isolation level xxxx;
注意:如果使用global則修改的是數據庫的默認隔離級別,所有新開的窗口的隔離級別繼承自這個默認隔離級別如果使用session修改,則修改的是當前客戶端的隔離級別,和數據庫默認隔離級別無關。當前的客戶端是什麼隔離級別,就能防止什麼隔離級別問題,和其他客戶端是什麼隔離級別無關。