一、資料庫事務
資料庫事務是指作為單個邏輯工作單元執行的一系列操作,可以認為事務就是一組不可分割的SQL語句
二、資料庫事務的ACID屬性
原子性(atomic)
事務必須是原子工作單元;對于其資料修改,要麼全都執行,要麼全都不執行。
一緻性(consistent)
事務在完成時,必須使所有的資料都保持一緻狀态。在相關資料庫中,所有規則都必須應用于事務
的修改,以保持所有資料的完整性。事務結束時,所有的内部資料結構(如B 樹索引或雙向鍊
表)都必須是正确的。
隔離性(insulation)
由并發事務所作的修改必須與任何其它并發事務所作的修改隔離。事務檢視資料時資料所處的狀
态,要麼是另一并發事務修改它之前的狀态,要麼是另一事務修改它之後的狀态,事務不會檢視中
間狀态的資料。
持久性(Duration)
事務完成之後,它對于系統的影響是永久性的。
三、事務的組成
一個資料庫事務可由:
一個或多個DML語句組成
一個DDL語句組成
一個DCL語句組成
一個資料事務由:
以第一個DML語句的執行作為開始
以下面的其中之一作為結束
commit (送出)
rollback (復原)
ddl或dcl語句 (自動送出)
使用者會話正常結束(自動送出)
系統異常終止 (自動復原)
系統崩潰 (自動復原)
四、事務的送出或復原(COMMIT、ROLLBACK)
--使用COMMIT事務,robinson記錄被插入到表
SQL> INSERT INTO scott.emp(empno,ename,job,salary)
2 VALUES(9999,'Robinson','DBA',3500);
1 row created.
SQL> COMMIT;
Commit complete.
SQL> UPDATE scott.emp SET salary = 4000 WHERE ename = 'Robinson';
1 row updated.
--使用ROLLBACK復原,更新将失效,最終結果如下面的查詢
SQL> ROLLBACK;
Rollback complete.
SQL> SELECT * FROM scott.emp WHERE ename = 'Robinson';
EMPNO ENAME JOB MGR HIREDATE SALARY DEPTNO
---------- ------------------------------ --------- ---------- --------- ---------- ----------
9999 Robinson DBA 3500
五、儲存點
設定儲存點:
SAVEPOINT NAME
恢複至儲存點:
ROLLBACK TO NAME
--檢視empno為,的記錄
SQL> SELECT * FROM scott.emp WHERE empno IN (1235,1236);
1235 Tony boy 28-JUN-10 7100
1236 Ben IT 28-JUN-10 3100 20
--首先更新empno 為的salary ,并設定了一個儲存點tran1
SQL> UPDATE scott.emp SET salary = salary * 1.5 WHERE empno = 1236;
SQL> SAVEPOINT tran1;
Savepoint created.
--更新empno 為的salary
SQL> UPDATE scott.emp SET salary = salary * 0.8 WHERE empno = 1235;
--檢視剛剛更新的兩條記錄
1235 Tony boy 28-JUN-10 5680
1236 Ben IT 28-JUN-10 4650 20
--将事務復原到儲存點tran1
SQL> ROLLBACK TO SAVEPOINT tran1;
--可以看到儲存點之後的修改被復原,而儲存點之前的修改則不受影響
--對所作的修改全部ROLLBACK,此時僅僅包含了empno 為的記錄,因為已經被復原
SQL> SELECT * FROM scott.emp WHERE empno IN (1235,1236);
六、事務的開始與結束及不同時刻的狀态
事務的開始
連接配接到資料并執行了一條DML語句(INSERT ,UPDATE,DELETE)
前一條事務結束後,又執行了另外一條DML語句
事務的結束
執行COMMIT 或ROLLBACK
執行DDL語句,則自動送出并結束事務
執行DCL語句,則自動送出并結束事務
斷開與資料庫的連接配接,如退出SQL Plus。
Windows下SQL Plus正常退出将執行COMMIT,如點選關閉視窗直接關閉則復原
X-Window下SQL Plus正常退出将執行COMMIT,如點選關閉視窗直接關閉則復原(筆者在RHEL5下測試如此)
DML語句執行失敗則自動復原
送出或復原前的資料狀态
改變前的資料狀态是可以恢複的
執行DML 操作的使用者可以通過SELECT 語句查詢之前的修正
其他使用者不能看到目前使用者所做的改變,直到目前使用者結束事務。
DML語句所涉及到的行被鎖定,其他使用者不能操作
送出後的資料狀态
資料的改變已經被儲存到資料庫中。
改變前的資料已經丢失。
所有使用者可以看到結果。
鎖被釋放,其他使用者可以操作涉及到的資料。
所有儲存點被釋放。
七、并發事務
多個使用者同時與資料庫互動,且每個使用者都可以同時通路自己的事物,這種事務稱為并發事務
對于同一個對象上運作的多個事務,僅當執行commit時才對彼此的查詢産生影響
下表中示範了并發事務的處理:
Trans1
Trans2
T1
SQL> SELECT COUNT(1) FROM emp;
COUNT(1)
----------
16
SQL> SELECT COUNT(1) FROM scott.emp;
T2
SQL> INSERT INTO emp(empno,ename,salary)
2 SELECT 6666,'Jenney',3000 FROM DUAL;
T3
SQL> UPDATE emp
2 SET salary = salary + 200 WHERE ename = 'SCOTT';
T4
17
T5
SQL> COMMIT;
T6
示例中顯示了兩個不同的事務交叉執行的順序,可以看出,僅當事務執行COMMIT後,相關事務才産生影響
八、利用AUTOCOMMIT進行事務控制
SET AUTOCOMMIT ON
設定自動送出,每執行一條語句,就送出。将autocommit設成ON時,在進行DML操作時似乎很友善,
但在實際應用中有時可能會出現問題,如,在有些應用中要同時對幾個表進行操作,對于這些表建立
了外鍵聯系,如果一旦操作失敗另一個表,就很麻煩了。
關于鎖及事物的隔離級别請關注後續文章