Oracle PL/SQL(14) - 事務(wù)

Oracle是基于事務(wù)的,Oracle以用戶事務(wù)來確保數(shù)據(jù)的完整性。一個(gè)事務(wù)即將一系列的數(shù)據(jù)操縱的sql語句作為一個(gè)邏輯單元,邏輯單元里面的單個(gè)操作要么全做,要么全部不做,以保證數(shù)據(jù)的完整性。

事務(wù)的特性:
原子性:事務(wù)是SQL中的最小執(zhí)行單位,不能再進(jìn)行分割。要么全部執(zhí)行,要么全部不執(zhí)行。
一致性:在事務(wù)操作前和事務(wù)操作后,數(shù)據(jù)必須處于一致狀態(tài)。
隔離性:事務(wù)之間是相互隔離的,多個(gè)事務(wù)不會(huì)相互影響。
持久性:當(dāng)事務(wù)提交后,數(shù)據(jù)則永久有效。

讀取事務(wù)異常:
臟讀:一個(gè)事務(wù)讀取了另一個(gè)事務(wù)未提交的數(shù)據(jù)。
不可重復(fù)讀:一個(gè)事務(wù)再次讀取之前曾經(jīng)讀取過的數(shù)據(jù)時(shí),發(fā)現(xiàn)該數(shù)據(jù)已經(jīng)被另一個(gè)已提交的事務(wù)修改。
幻讀:一個(gè)事務(wù)根據(jù)相同的查詢條件,重新執(zhí)行查詢,返回記錄中包含了與前一次執(zhí)行查詢返回的記錄不同的行。

事務(wù)控制語句:
COMMIT:提交事務(wù),對(duì)數(shù)據(jù)庫的修改進(jìn)行保存。
ROLLBACK:回滾事務(wù),取消對(duì)數(shù)據(jù)庫所做的修改。
SAVEPOINT:在事務(wù)中創(chuàng)建存儲(chǔ)點(diǎn)。
ROLLBACK TO <SAVEPOINT>:將事務(wù)回滾到存儲(chǔ)點(diǎn)。
SET TRANSACTION:設(shè)置事務(wù)的屬性。
PRAGMA AUTONOMOUS_TRANSACTION:創(chuàng)建自治事務(wù)。

使用事務(wù)的步驟:
第1步、開啟事務(wù)。在Oracle中,事務(wù)是在上一次事務(wù)結(jié)束以后,數(shù)據(jù)“第一次”被修改時(shí)自動(dòng)開啟。
第2步、進(jìn)行(多次)數(shù)據(jù)操作(增、刪、改)。
第3步、結(jié)束事務(wù):事務(wù)結(jié)束有兩種情況.
(1)事務(wù)被提交:
a.發(fā)出COMMIT命令。
b.執(zhí)行DDL語句。如果DDL語句前面有DML語句,則Oracle會(huì)自動(dòng)把前面的DML語句作為一個(gè)事務(wù)提交。
c.與Oracle斷開連接,或退出PL/SQL Developer,事務(wù)會(huì)自動(dòng)提交。
2)數(shù)據(jù)被撤銷:
a.發(fā)出ROOLBACK命令.
b.服務(wù)器進(jìn)程異常結(jié)束。
c.DBA停止會(huì)話。

1、設(shè)置事務(wù)隔離級(jí)別
Oracle / PLSQL中SET TRANSACTION語句的語法是:

SET TRANSACTION [ READ ONLY | READ WRITE ]
               [ ISOLATION LEVEL [ SERIALIZE | READ COMMITED ]
               [ USE ROLLBACK SEGMENT 'segment_name' ]
               [ NAME 'transaction_name' ];

READ ONLY - 可選的。 如果指定,它將事務(wù)設(shè)置為只讀事務(wù)。
READ WRITE - 可選的。 如果指定,它將事務(wù)設(shè)置為讀/寫事務(wù)。
ISOLATION LEVEL - 可選的。 如果指定,它有兩個(gè)選項(xiàng):
ISOLATION LEVEL SERIALIZE - 如果事務(wù)嘗試更新由另一個(gè)事務(wù)更新并未提交的資源,則事務(wù)將失敗。
ISOLATION LEVEL READ COMMITTED - 如果事務(wù)需要另一個(gè)事務(wù)持有的行鎖,則事務(wù)將等待,直到行鎖被釋放。
USE ROLLBACK SEGMENT - 可選的。 如果指定,它將事務(wù)分配給由'segment_name'標(biāo)識(shí)的保存點(diǎn),該段是用引號(hào)括起來的段名稱。
NAME - 為'transaction_name'標(biāo)識(shí)的事務(wù)分配一個(gè)名稱,該事務(wù)用引號(hào)括起來。
例如:

-- 設(shè)置事務(wù)為只讀事務(wù),這在生成報(bào)告,賬單等時(shí)特別有用
SET TRANSACTION READ ONLY NAME 'tran';
SELECT * FROM TEST;
COMMIT; -- 提交事務(wù),只讀事務(wù)也需要提交的哦

-- 指定事務(wù)的隔離級(jí)別
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE NAME 'tran';
-- SET TRANSACTION ISOLATION LEVEL READ COMMITTED NAME 'tran'; -- 事務(wù)默認(rèn)的隔離級(jí)別是 READ COMMITTED
SELECT * FROM TEST;
COMMIT; -- 提交事務(wù)

-- 指定當(dāng)事務(wù)失敗時(shí),將事務(wù)回滾到指定的回滾段
SET TRANSACTION USE ROLLBACK SEGMENT test NAME 'tran';
INSERT INTO TEST VALUES ('Scott');
ROLLBACK; -- 回滾事務(wù)

2、存儲(chǔ)過程事務(wù)使用斷點(diǎn)回滾
創(chuàng)建表

CREATE TABLE demo(description nvarchar2 (1000));
INSERT INTO demo VALUES ('test');

創(chuàng)建存儲(chǔ)過程

CREATE OR REPLACE PROCEDURE rollback_point
IS
BEGIN
  UPDATE   demo
     SET   description = 'savapoint 1';
  SAVEPOINT p1;

  UPDATE   demo
     SET   description = 'savapoint p1';
  SAVEPOINT p2;

  ROLLBACK TO SAVEPOINT p1;
  --ROLLBACK; --會(huì)回滾整個(gè)事務(wù)處理。
  COMMIT;
EXCEPTION
  WHEN OTHERS
  THEN
     DBMS_OUTPUT.put_line ('demo');
END rollback_point;

保存點(diǎn)(SAVEPOINT) 是事務(wù)處理過程中的一個(gè)標(biāo)志,與回滾命令 (ROLLBACK) 結(jié)合使用,主要的用途是允許用戶將某一段處理回滾而不必回滾整個(gè)事務(wù)。
如果定義了多個(gè) savepoint ,當(dāng)指定回滾到某個(gè) savepoint 時(shí),那么回滾操作將回滾這個(gè) savepoint 后面的所有操作。
如果不使用 ROLLBACK TO savepoint_name 而使用 ROLLBACK ,將會(huì)回滾整個(gè)事務(wù)處理。

3、自治事務(wù)與非自治事務(wù)
項(xiàng)目中,如果子程序 A 調(diào)用 B,那么 A 和 B 將在同一個(gè)事務(wù)中,A 或 B 中的任意一個(gè) COMMIT 語句將會(huì)使 A 和 B 所做的所有更改全部提交。如果想讓 B 在自己的事務(wù)中,無論 A 成功或失敗都不影響 B,該如何處理呢?這里就要用到自治事務(wù)。

自治事務(wù)(autonomous transaction)是PL/SQL靜態(tài)SQL的一個(gè)特性,它允許創(chuàng)建一個(gè)"事務(wù)中的事務(wù)",能獨(dú)立于其主事務(wù)提交或回滾。利用自治事務(wù),可以掛起當(dāng)前執(zhí)行的事務(wù),開始一個(gè)新事務(wù),完成一些工作,然后提交或回滾,所有這些都不影響當(dāng)前所執(zhí)行事務(wù)的狀態(tài)。自治事務(wù)可以用來記錄日志,記錄計(jì)數(shù)值。

要?jiǎng)?chuàng)建一個(gè)自治事務(wù),必須在匿名塊的最高層或者存儲(chǔ)過程、函數(shù)、數(shù)據(jù)包或觸發(fā)的定義部分中,使用PL/SQL中的PRAGMA AUTONOMOUS_TRANSACTION語句。在這樣的模塊或過程中執(zhí)行的SQL語句都是自治的。

以下例子演示自治事務(wù)如何工作
--創(chuàng)建測(cè)試表用于保存信息

Create table Msg (Msg varchar(50)) ;

--創(chuàng)建自治事務(wù)的存儲(chǔ)過程

create or replace procedure AutoNomouse_Insert is
    PRAGMA AUTONOMOUS_TRANSACTION;--指示自治事務(wù)語句
    begin
            insert into Msg values('AutoNomouse Insert');
           commit;
   end;

--創(chuàng)建非自治事務(wù)存儲(chǔ)過程

CREATE OR REPLACE Procedure NonAutoNomouse_Insert as
   begin
          insert into Msg Values('NonAutonomouse Insert');
          commit;
   end;

調(diào)用非自治事務(wù)的存儲(chǔ)過程

begin
 insert into Msg Values('This Main Info');
 NonAutoNomouse_Insert;
 rollback;
end;

查詢表中當(dāng)前的數(shù)據(jù)

select * from msg;

結(jié)果為:
MSG


This Main Info
NonAutonomouse Insert

因?yàn)檫^程中有COMMIT;所以RULLBACK 不起作用;
由此得出:非自治事務(wù)中的COMMIT,ROLLBACK是會(huì)影響整個(gè)事務(wù)的。
下面我們看一個(gè)另外一種情況:
刪除表中的數(shù)據(jù),不COMMIT提交

delete msg;

再次調(diào)用非自治事務(wù)的存儲(chǔ)過程

begin
   insert into Msg Values('This Main Info');
   rollback;  --這里加了ROLLBACK;
   NonAutoNomouse_Insert;
   rollback;
 end;

查詢表中當(dāng)前的數(shù)據(jù)

select * from msg;

結(jié)果為:
MSG


This Main Info
NonAutonomouse Insert
NonAutonomouse Insert

因?yàn)楫?dāng)前的調(diào)用是一個(gè)新的SESSION,前面的刪除操作并沒有提交,再次調(diào)用時(shí)被自動(dòng)提交; 所以會(huì)看到三行數(shù)據(jù)。
刪除表中的數(shù)據(jù),COMMIT提交

delete msg;
commit;

查詢表中當(dāng)前的數(shù)據(jù)

select * from msg;

結(jié)果為:
MSG


可以看到這里是正常的提交;

下面看一下自制事務(wù):

begin
insert into Msg Values('This Main Info');
AutoNomouse_Insert;
rollback;
end;

查詢表中當(dāng)前的數(shù)據(jù)

select * from msg;

結(jié)果為:
MSG


AutoNomouse Insert
結(jié)果是一行數(shù)據(jù),可以看到自治事務(wù)過程中的commit只把它本身的事務(wù)提交了,而對(duì)于父事務(wù)的語句沒有起到作用,而父事務(wù)中的rollback對(duì)自治事務(wù)中的語句也沒有作用。

總結(jié)自主事務(wù):
  1)、自主事務(wù)處理結(jié)果的變化不依賴于主事務(wù)處理的狀態(tài)或最終配置。
  2)、自主事務(wù)處理提交或回滾時(shí),不影響主事務(wù)處理的結(jié)果。
  3)、自主事務(wù)提交一旦提交,該自主事務(wù)處理結(jié)果的變化對(duì)于其他事務(wù)處理就是課件的。這意味著,用于可以訪問已更新的信息,無需等待主事務(wù)處理提交。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容