AUTONOMOUS TRANSACTION(自治事務)的介紹(轉)
AUTONOMOUS TRANSACTION(自治事務)的介紹 |
在基於低版本的ORACLE做一些專案的過程中,有時會遇到一些頭疼的問題.,比如想在執行當前一個由多個DML組成的transaction(事務)時,為每一步DML記錄一些資訊到跟蹤表中,由於事務的原子性,這些跟蹤資訊的提交將決定於主事務的commit或rollback. 這樣一來寫程式的難度就增大了, 程式設計師不得不把這些跟蹤資訊記錄到類似陣列的結構中,然後在主事務結束後把它們存入跟蹤表.哎,真是麻煩! 有沒有一個簡單的方法解決類似問題呢? ORACLE8i的AUTONOMOUS TRANSACTION(自治事務,以下AT)是一個很好的回答。 AT 是由主事務(以下MT)呼叫但是獨立於它的事務。在AT被呼叫執行時,MT被掛起,在AT內部,一系列的DML可以被執行並且commit或rollback. 注意由於AT的獨立性,它的commit和rollback並不影響MT的執行效果。在AT執行結束後,主事務獲得控制權,又可以繼續執行了。 如何實現AT的定義呢?我們來看一下它的語法。其實非常簡單。 只需下列PL/SQL的宣告部分加上PRAGMA AUTONOMOUS_TRANSACTION 就可以了。 1.頂級的匿名PL/SQL塊 2.Functions 或 Procedure(獨立宣告或宣告在package中都可) 3.SQL Object Type的方法 4.觸發器。 比如: 在一個獨立的procedure中宣告AT CREATE OR REPLACE PROCEDURE Log_error(error_msg IN VARCHAR2(100)) IS PRAGMA AUTONOMOUS_TRANSACTION; BEGIN Insert into Error_log values ( sysdate,error_msg); COMMIT; END; 下面我們來看一個例子,(win2000 advanced server + oracle8.1.6 , connect as scott) 建立一個表: create table msg (msg varchar2(120)); 首先,用普通的事務寫個匿名PL/SQL塊: declare cnt number := -1; --} Global variables procedure local is begin select count(*) into cnt from msg; dbms_output.put_line('local: # of rows is '||cnt); insert into msg values ('New Record'); commit; end; begin delete from msg ; commit; insert into msg values ('Row 1'); local; select count(*) into cnt from msg; dbms_output.put_line('main: # of rows is '||cnt); rollback; local; insert into msg values ('Row 2'); commit; local; select count(*) into cnt from msg; dbms_output.put_line('main: # of rows is '||cnt); end; 執行結果(注意開啟serveroutput) local: # of rows is 1 -> 子程式local中可以’看到’主匿名塊中的uncommitted記錄 main: # of rows is 2 -> 主匿名塊可以’看到’2條記錄(它們都是被local commit掉的) local: # of rows is 2 -> 子程式local首先’看到’2條記錄,然後又commit了第三條記錄 local: # of rows is 4 -> 子程式local又’看到’了新增加的記錄(它們都是被local commit掉的),然後又commit了第五條記錄 main: # of rows is 5 -> 主匿名塊最後’看到’了所有的記錄. 從這個例子中,我們看到COMMIT和ROLLBACK的位置無論是在主匿名塊中或者在子程式中,都會影響到整個當前事務. 現在用AT改寫一下匿名塊中的procedure local: ... procedure local is pragma AUTONOMOUS_TRANSACTION; begin ... 重新執行(注意開啟serveroutput) local: # of rows is 0 -> 子程式local中無法可以’看到’主匿名塊中的uncommitted記錄 (因為它是獨立的) main: # of rows is 2 -> 主匿名塊可以’看到’2條記錄,但只有一條是被commited. local: # of rows is 1 -> 子程式local中可以’看到’它前一次commit的記錄,但是主匿名塊中的記錄已經被提前rollback了 local: # of rows is 3 -> 子程式local 中可以’看到’3條記錄包括主匿名塊commit的記錄 main: # of rows is 4 ->主匿名塊最後’看到’了所有的記錄. 很明顯,AT是獨立的,在它執行時,MT被暫停了. AT的COMMIT,ROLLBACK並不影響MT的執行. 運用AT時,有一些注意事項,簡單列舉如下: 1. 在匿名PL/SQL塊中,只有頂級的匿名PL/SQL塊可以被設為AT 2. 如果AT試圖訪問被MT控制的資源,可能有deadlock發生. 3. Package 不能被宣告為AT,只有package所擁有的function和procedure 才能宣告為AT 4. AT程式必須以commit 或rollback結尾,否則會產生Oracle 錯誤ORA-06519: active autonomous transaction detected and rolled back 在程式開發時,如果充分運用AUTONOMOUS TRANSACTION的特性,一定能取得事倍功半的效果. 參考資料: metalink.oracle.com oracle8i manual log: idle>truncate table msg; Table truncated. idle>---normal idle>declare 2 cnt number := -1; --} Global variables 3 procedure local is 4 begin 5 select count(*) into cnt from msg; 6 dbms_output.put_line('local: # of rows is '||cnt); 7 insert into msg values ('New Record'); 8 commit; 9 end; 10 11 begin 12 delete from msg ; 13 commit; 14 insert into msg values ('Row 1'); 15 local; 16 select count(*) into cnt from msg; 17 dbms_output.put_line('main: # of rows is '||cnt); 18 rollback; 19 20 local; 21 insert into msg values ('Row 2'); 22 commit; 23 24 local; 25 select count(*) into cnt from msg; 26 dbms_output.put_line('main: # of rows is '||cnt); 27 end; 28 / local: # of rows is 1 main: # of rows is 2 local: # of rows is 2 local: # of rows is 4 main: # of rows is 5 PL/SQL procedure successfully completed. idle>---AT idle>declare 2 cnt number := -1; --} Global variables 3 procedure local is 4 pragma AUTONOMOUS_TRANSACTION; 5 begin 6 select count(*) into cnt from msg; 7 dbms_output.put_line('local: # of rows is '||cnt); 8 insert into msg values ('New Record'); 9 commit; 10 end; 11 12 begin 13 delete from msg ; 14 commit; 15 insert into msg values ('Row 1'); 16 local; 17 select count(*) into cnt from msg; 18 dbms_output.put_line('main: # of rows is '||cnt); 19 rollback; 20 21 local; 22 insert into msg values ('Row 2'); 23 commit; 24 25 local; 26 select count(*) into cnt from msg; 27 dbms_output.put_line('main: # of rows is '||cnt); 28 end; 29 / local: # of rows is 0 main: # of rows is 2 local: # of rows is 1 local: # of rows is 3 main: # of rows is 4 PL/SQL procedure successfully completed. |
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/756652/viewspace-242082/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle 巢狀事務 VS 自治事務Oracle巢狀
- 事務的介紹
- xshell-ssh自動多級跳轉功能介紹
- 一起玩轉微服務(10)——spring boot介紹微服務Spring Boot
- DAPPER 事務 TRANSACTIONAPP
- indexedDB transaction 事務Index
- PostgreSQL DBA(68) - 使用DBLink實現自治事務SQL
- 【轉】恢復archivelog介紹Hive
- PostgreSQL 原始碼解讀(228)- Transaction(事務系統簡介)SQL原始碼
- silky微服務框架的服務治理介紹微服務框架
- SpringCloud包含的微服務介紹--EurekaSpringGCCloud微服務
- Django處理事務:transactionDjango
- Bootstrap Blazor 元件介紹 Table (一)自動生成列功能介紹bootBlazor元件
- 分散式事務介紹分散式
- django自帶的許可權介紹(rbac)Django
- Nginx服務詳細介紹Nginx
- 【Nacos】微服務配置中心介紹微服務
- JMS訊息服務介紹
- 【轉】jenkins外掛pipeline使用介紹Jenkins
- SONM最新路線圖介紹(轉)
- 微服務架構的特徵簡要介紹微服務架構特徵
- 從 RGB 到 HSV 的轉換詳細介紹
- 【微服務目錄】.NET Core 微服務介紹微服務
- 四.unittest介面自動化框架介紹框架
- SAE自動駕駛分級介紹自動駕駛
- Python自動化測試框架介紹Python框架
- 自動化運維工具Ansible介紹運維
- Selenium用法 - - 自動化測試介紹
- Flume架構以及應用介紹[轉]架構
- dotnet core微服務框架Jimu介紹微服務框架
- 微服務 Spring cloud 各元件介紹微服務SpringCloud元件
- lms微服務框架主機介紹微服務框架
- Linux服務管理神器:SYSTEMD介紹Linux
- 服務端Swift Vagrant 工具介紹服務端Swift
- 自動化運維的發展趨勢介紹!運維
- Spring @Transaction 註解是如何執行事務的?Spring
- 微服務系列(二)GRPC的介紹與安裝微服務RPC
- MySQL事務提交的三個階段介紹MySql