Mysql事務

 

Mysql事務

1、概述 

事務可以保證多個操作原子性,要麼全成功,要麼全失敗。對於數據庫來說事務保證批量的DML要麼全成功,要麼全失敗。事務具有四個特徵ACID

    1. 原子性(Atomicity)
      1. 整個事務中的所有操作,必須作爲一個單元全部完成(或全部取消)。
    2. 一致性(Consistency)
      1. 在事務開始之前與結束之後,數據庫都保持一致狀態。
    3. 隔離性(Isolation)
      1. 一個事務不會影響其他事務的運行。
    4. 持久性(Durability)
      1. 在事務完成以後,該事務對數據庫所作的更改將持久地保存在數據庫之中,並不會被回滾。

事務中存在一些概念:

  1. 事務(Transaction):一批操作(一組DML)
  2. 開啓事務(Start Transaction)
  3. 回滾事務(rollback)
  4. 提交事務(commit)
  5. SET AUTOCOMMIT:禁用或啓用事務的自動提交模式

 

當執行DML語句是其實就是開啓一個事務

關於事務的回滾需要注意:只能回滾insert、delete和update語句,不能回滾select(回滾select沒有任何意義),對於create、drop、alter這些無法回滾.

事務只對DML有效果。

 

注意:rollback,或者commit後事務就結束了。

16.2、事務的提交與回滾演示 

創建表

 

create table user(

id int (11) primary key not null auto_increment ,
     username varchar(30),

password varchar(30)

)  ENGINE=InnoDB DEFAULT CHARSET=utf8

 

 

  1. 查詢表中數據
  2. 開啓事務START TRANSACTION;
  3. 插入數據 insert into user (username,password) values ('zhangsan','123')
  4. 查看數據  一條記錄已經插入到表中
  5. 修改數據  表中數據已經被修改
  6. 查看數據  之前所做的操作已經“生效”
  7. 回滾事務  事務進行回滾,撤銷之前的操作
  8. 查看數據  回覆操作之前的狀態

 

3、自動提交模式

  • 自動提交模式用於決定新事務如何及何時啓動。 
  • 啓用自動提交模式:
    • 如果自動提交模式被啓用,則單條DML語句將缺省地開始一個新的事務。 
    • 如果該語句執行成功,事務將自動提交,並永久地保存該語句的執行結果。 
    • 如果語句執行失敗,事務將自動回滾,並取消該語句的結果。 
    • 在自動提交模式下,仍可使用START TRANSACTION語句來顯式地啓動事務。這時,一個事務仍可包含多條語句,直到這些語句被統一提交或回滾。 
  • 禁用自動提交模式: 
    • 如果禁用自動提交,事務可以跨越多條語句。 
    • 在這種情況下,事務可以用COMMIT和ROLLBACK語句來顯式地提交或回滾。 
  • 自動提交模式可以通過服務器變量AUTOCOMMIT來控制。 
  • 例如:

mysql> SET AUTOCOMMIT = OFF; 

mysql> SET AUTOCOMMIT = ON; 

mysql> SET SESSION AUTOCOMMIT = OFF; 

mysql> SET SESSION AUTOCOMMIT = ON; 

show variables like '%auto%'; -- 查看變量狀態

4、事務的隔離級別

4.1、隔離級別

  • 事務的隔離級別決定了事務之間可見的級別。
  • 當多個客戶端併發地訪問同一個表時,可能出現下面的一致性問題:
  • 髒讀取(Dirty Read) 一個事務開始讀取了某行數據,但是另外一個事務已經更新了此數據但沒有能夠及時提交,這就出現了髒讀取。
  • 不可重複讀(Non-repeatable Read) 在同一個事務中,同一個讀操作對同一個數據的前後兩次讀取產生了不同的結果,這就是不可重複讀。
  • 幻像讀(Phantom Read) 幻像讀是指在同一個事務中以前沒有的行,由於其他事務的提交而出現的新行。

4.2、四個隔離級別

  • InnoDB 實現了四個隔離級別,用以控制事務所做的修改,並將修改通告至其它併發的事務:
  • 讀未提交(READ UMCOMMITTED) 允許一個事務可以看到其他事務未提交的修改。
  • 讀已提交(READ COMMITTED) 允許一個事務只能看到其他事務已經提交的修改,未提交的修改是不可見的。
  • 可重複讀(REPEATABLE READ) 確保如果在一個事務中執行兩次相同的SELECT語句,都能得到相同的結果,不管其他事務是否提交這些修改。 (銀行總賬)該隔離級別爲InnoDB的缺省設置
  • 串行化(SERIALIZABLE) 【序列化】將一個事務與其他事務完全地隔離。 (不常用)

例:A可以開啓事物,B也可以開啓事物

A在事物中執行DML語句時,未提交

B不以執行DML,DQL語句

4.3、隔離級別與一致性問題的關係

 

4.4、設置服務器缺省隔離級別

通過修改配置文件設置

  • 可以在my.ini文件中使用transaction-isolation選項來設置服務器的缺省事務隔離級別。 
  • 該選項值可以是: 
    • READ-UNCOMMITTED
    • READ-COMMITTED
    • REPEATABLE-READ
    • SERIALIZABLE
  • 例如:
[mysqld]

transaction-isolation = READ-COMMITTED

通過命令動態設置隔離級別

  • 隔離級別也可以在運行的服務器中動態設置,應使用SET TRANSACTION ISOLATION LEVEL語句。 
  • 其語法模式爲:
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL <isolation-level>

其中的<isolation-level>可以是:

    • READ UNCOMMITTED
    • READ COMMITTED
    • REPEATABLE READ
    • SERIALIZABLE
  • 例如: 
    SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

     

4.5、隔離級別的作用範圍

  • 事務隔離級別的作用範圍分爲兩種: 
    • 全局級:對所有的會話有效 
    • 會話級:只對當前的會話有效 
  • 例如,設置會話級隔離級別爲READ COMMITTED :
mysql> SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

或:

mysql> SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
  • 設置全局級隔離級別爲READ COMMITTED :
mysql> SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;

4.6、查看隔離級別

  • 服務器變量tx_isolation(包括會話級和全局級兩個變量)中保存着當前的會話隔離級別。 
  • 爲了查看當前隔離級別,可訪問tx_isolation變量: 
  • 查看會話級的當前隔離級別:
mysql> SELECT @@tx_isolation;

或: 

mysql> SELECT @@session.tx_isolation;
  • 查看全局級的當前隔離級別: 
mysql> SELECT @@global.tx_isolation;

4.7、併發事務與隔離級別示例

read uncommitted(未提交讀) --髒讀(Drity Read):

會話一

會話二

mysql> prompt s1>

mysql> use bjpowernode

s1>use bjpowernode

mysql> prompt s2>

s1>create table tx (

id int(11),

num int (10)

);

 

s1>set global transaction isolation level read uncommitted;

 

s1>start transaction;

 

 

s2>start transaction;

s1>insert into tx values (1,10);

 

 

s2>select * from tx;

s1>rollback;

 

 

s2>select * from tx;

 

read committed(已提交讀)

會話一

會話二

s1> set global transaction isolation level read committed;

 

s1>start transaction;

 

 

s2>start transaction;

s1>insert into tx values (1,10);

 

s1>select * from tx;

 

 

s2>select * from tx;

s1>commit;

 

 

s2>select * from tx;

repeatable read(可重複讀)

會話一

會話二

s1> set global transaction isolation level repeatable read;

 

s1>start transaction;

s2>start transaction;

s1>select * from tx;

 

s1>insert into tx values (1,10);

 

 

s2>select * from tx;

s1>commit;

 

 

s2>select * from tx;

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