1. 程式人生 > 其它 >SQL/事務控制語言TCL(Transaction Control Language)

SQL/事務控制語言TCL(Transaction Control Language)

  儲存點: SAVEPOINT
  設定事務: SET TRANSACTION
  提交:COMMIT
  回滾:ROLLBACK

#TCL

/*
Transction Control Language 事務控制語言

事務:
一個或一組sql語句組成一個執行單元,這個執行單元要麼全部執行,要麼全部不執行

#案例:轉賬
張三丰 1000
郭襄   1000

update 表 set 張三丰的餘額 = 500 where name = '張三丰'
意外
update 表 set 郭襄的餘額 = 1500 where name = '郭襄'

事務的特性:ACID    
原子性 Atomicity:  一個事務不可再分割,要麼都執行要麼都不執行
一致性 Consistency:一個事務執行會使資料從一個一致狀態切換到另外一個一致狀態
隔離性 Isolation:  一個事務的執行不受其他事務的干擾
永續性 Durability: 一個事務一旦提交,則會永久的改變資料庫的資料

MySQL中的儲存引擎
1、在MySQL中的資料用各種不同的技術儲存在檔案或記憶體中
2、通過show engines; 來檢視MySQL支援的儲存引擎
3、在MySQL中用的最多的儲存引擎有:innodb,myisam,memory,
    其中innodb支援事務,myisam,memory等不支援事務

事務的建立
隱式的事務:事務沒有明顯的開啟和結束的標記
比如insert、update、 delete語句

delete from 表 where id = 1;  #這就是一個事務 # SHOW VARIABLES LIKE 'autocommit'; # 預設開啟

顯式事務:事務具有明顯的開啟和結束的標記
前提:必須先設定自動提交功能為禁用

set autocommit = 0;

步驟1:開啟事務
set autocommit = 0;   #只對當前會話有效
【start transaction;】#開啟事務,可選

步驟2:編寫事務中的sql語句(insert update delete select)
語句1;
語句2;
...

步驟3:結束事務
commit;     #提交事務,相當於儲存到庫,沒提交相當於在記憶體更新(insert update delete)
# rollback; #回滾事務,相當於在記憶體撤銷

savepoint 結點名; #設定儲存點



開始事務的語句;
update 表 set 張三丰的餘額 = 500 where name = '張三丰'

update 表 set 郭襄的餘額 = 1500 where name = '郭襄'
結束事務的語句;

#對於同時執行多個事務,當這些事務訪問資料庫中相同的資料時,
#如果沒有采取必要的隔離機制,會導致各種併發問題
1、髒讀:對於兩個事務t1,t2,t1讀取了已經被t2更新但還沒有提交(沒有提交)的欄位之後,
    若t2回滾,t1讀取的內容就是臨時且無效的(t1直接讀取的應該是t2修改的記憶體)
2、不可重複讀:對於兩個事務t1,t2,t1讀取了一個欄位,然後t2更新(提交)了該欄位之後,
    t1再次讀取同一個欄位,值就不同了
3、幻讀:對於兩個事務t1,t2,t1從一個表中讀取了一個欄位,然後t2在該表中插入(插入)了一些新的行(提交)之後,
    如果t1再次讀取同一個表,就會多出幾行
    
#4種事務隔離級別:
1、read uncommitted: 讀未提交資料,(允許事務讀取未被提交的變更,髒讀、不可以重複讀、幻讀的問題都會出現)
2、read committed:  讀取提交的資料,(只允許事務讀取已經被其他事務提交的變更,
    可以避免髒讀,但不可重複讀和幻讀的問題仍然可能出現)
3、repeatable read: 可重複讀,  確保事務可以多次從一個欄位中讀取相同的值,
    在這個事務持續期間,禁止其他事務對這個欄位進行更新,
    可以避免髒讀和不可重複讀,但幻讀的問題仍然存在
4、serializable: 序列化,確保可以從一個表中讀取相同的行,在這個事務持續期間,
    禁止其他事務對該表執行插入、更新和刪除操作,所有併發問題都可以避免,但效能十分低下
    
Oracle 支援2種事務隔離級別:read commited, serializable,預設:read committed
MySQL 支援4中事務隔離級別: 預設隔離級別: repeatable read

MySQL 

#檢視隔離級別
select @@tx_isolation;
#設定當前MySQL連線的隔離級別     #session
set session transaction isolation level read uncommitted;
#設定資料庫系統的全域性的隔離級別  #global
set global transaction isolation level read committed;

#開啟事務
set autocommit = 0; #第一步,(顯式的)設定自動提交為禁用 #(隱式)預設是自動提交

#設定字符集
use 庫名;
set names 字符集; #比如gbk utf8

*/ SHOW VARIABLES LIKE 'autocommit'; #提交預設開啟 #show engines; DROP TABLE IF EXISTS account; CREATE TABLE account( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(20), balance DOUBLE ); INSERT INTO account(username,balance) VALUE('張無忌',1000),('趙敏',1000); #演示事務的使用步驟 #開啟事務 SET autocommit = 0; START
TRANSACTION; #編寫一組事務的語句 UPDATE account SET balance = 500 WHERE username = '張無忌'; UPDATE account SET balance = 1500 WHERE username = '趙敏'; #結束事務 #commit; #提交 ROLLBACK; #回滾 SELECT * FROM account; #設定字符集 #set names gbk 只不過是把client、connection和resultset轉成gbk /* #開啟庫 use 庫; #設定字符集 set names 字符集; */ USE
test; SET NAMES gbk; # #savepoint的使用 SET autocommit = 0; #設定一個事務 START TRANSACTION; DELETE FROM account WHERE id = 25; SAVEPOINT a; #設定儲存點 DELETE FROM account WHERE id = 28; ROLLBACK TO a; #回滾到儲存點 SELECT * FROM account; #查看錶account,id = 25的刪除,28的沒有刪除 #delete 和 truncate在事務使用時的區別 #delete SET autocommite = 0; START TRANSACTION; DELETE FROM account; ROLLBACK; SELECT *FROM account; #truncate #不支援 rollback SET autocommite = 0; START TRANSACTION; TRUNCATE TABLE account; ROLLBACK; SELECT * FROM account; #檢視,沒有回滾
View Code