MySQL數據庫進階(事務Transaction)

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");

1
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;

2

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的數據
3

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修改,則修改的是當前客戶端的隔離級別,和數據庫默認隔離級別無關。當前的客戶端是什麼隔離級別,就能防止什麼隔離級別問題,和其他客戶端是什麼隔離級別無關。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章