`

oracle 存储过程 pragma autonomous_transaction

 
阅读更多

PRAGMA AUTONOMOUS_TRANSACTION

 
 

数据库事务是一种单元操作,要么是全部操作都成功,要么全部失败。在Oracle中,一个事务是从执行第一个数据管理语言(DML)语句开始,直到执行一个COMMIT语句,提交保存这个事务,或者执行一个ROLLBACK语句,放弃此次操作结束。

 

事务的“要么全部完成,要么什么都没完成”的本性会使将错误信息记入数据库表中变得很困难,因为当事务失败重新运行时,用来编写日志条目的INSERT语句还未完成。

 

针对这种困境,Oracle提供了一种便捷的方法,即自治事务。自治事务从当前事务开始,在其自身的语境中执行。它们能独立地被提交或重新运行,而不影响正在运行的事务。正因为这样,它们成了编写错误日志表格的理想形式。在事务中检测到错误时,您可以在错误日志表格中插入一行并提交它,然后在不丢失这次插入的情况下回滚主事务。

 

因为自治事务是与主事务相分离的,所以它不能检测到被修改过的行的当前状态。这就好像在主事务提交之前,它们一直处于单独的会话里,对自治事务来说,它们是不可用的。然而,反过来情况就不同了:主事务能够检测到已经执行过的自治事务的结果。

 

要创建一个自治事务,您必须在匿名块的最高层或者存储过程、函数、数据包或触发的定义部分中,使用PL/SQL中的PRAGMA AUTONOMOUS_TRANSACTION语句。在这样的模块或过程中执行的SQL Server语句都是自治的。

 

触发无法包含COMMIT语句,除非有PRAGMA AUTONOMOUS_TRANSACTION标记。但是,只有触发中的语句才能被提交,主事务则不行。

exp:

Create table Msg (Msg varchar(50)) ;
自制事务:
create or replace procedure AutoNomouse_Insert is
     PRAGMA AUTONOMOUS_TRANSACTION;
     begin
             insert into Msg values('AutoNomouse Insert');
            commit;
    end;
非自治事务:
CREATE OR REPLACE Procedure NonAutoNomouse_Insert as
    begin
           insert into Msg Values('NonAutonomouse Insert');
           commit;
    end;

SQL> begin
  
  3            insert into Msg Values('This Main Info');
  
  5            NonAutoNomouse_Insert;
  
  7            rollback;
  
   end
 10  ;
 11  /
 
PL/SQL procedure successfully completed
 
SQL> select * from msg;
 
MSG
--------------------------------------------------
This Main Info
NonAutonomouse Insert
因为过程中有COMMIT;所以匿名块中得RULLBACK 是不起作用的; 由此得出:非自治事务中的COMMIT,ROLLBACK
是会影响整个事务的。
下面我们看一个另外一种情况:
SQL> delete msg;
 
2 rows deleted
 
SQL>
 
这里没有COMMIT;

SQL> begin
  
  3            insert into Msg Values('This Main Info');
  
  5            rollback;  --这里加了ROLLBACK;
  
  7            NonAutoNomouse_Insert;
  
  9            rollback;
 10 
 11  end
 12  ;
 13  /
 
PL/SQL procedure successfully completed
 
SQL> select * from msg;
 
MSG
--------------------------------------------------
This Main Info
NonAutonomouse Insert
NonAutonomouse Insert
 
竟然没有ROLLBACK (DELETE * FROM SSG ;) 为什么了? 因为过程就是一个新的SESSION,所以前面的SESSION
被正常EXIT,同时被自动提交; 所以我们会看到三行数据。
SQL> commit;
 
Commit complete
 
SQL> select * from msg;
 
MSG
--------------------------------------------------
This Main Info
NonAutonomouse Insert
NonAutonomouse Insert
 
SQL> commit;
 
Commit complete
 
SQL> select * from msg;
 
MSG
--------------------------------------------------
This Main Info
NonAutonomouse Insert
NonAutonomouse Insert
因为这里一个新的SESSION 所以是没有意义的事务控制语句。
 
SQL> delete msg;
 
3 rows deleted
 
SQL> commit;
 
Commit complete
 
SQL> select * from msg;
 
MSG
--------------------------------------------------
可以看到这里是正常的提交;
 
下面看一下自制事务:
SQL> begin
  
  3            insert into Msg Values('This Main Info');
  
  5            AutoNomouse_Insert;
  
  7            rollback;
  
   end
 10 
 11  ;
 12  /
 
PL/SQL procedure successfully completed
 
SQL> select * from msg;
 
MSG
--------------------------------------------------
AutoNomouse Insert
 
我们看到是一行数据,显然第一条SQL INSERT 是被ROLLBACK,证明自制事务是一个独立于主程序的事务,
他不会对主事务的控制产生影响。另外在分布式环境中我们经常会遇到 ORA-02064 ERROR ,就是因为主事务
自己有事务控制语句,然而被调用的远程过程也有自己的事物控制语句,当然就会报错,我们将被调用的过程
声明为自制事务那就OK了。
分享到:
评论

相关推荐

    Oracle自治事务的介绍(Autonomous_Transactions)

    Oracle自治事务的介绍(Autonomous_Transactions)PRAGMA_AUTONOMOUS_TRANSACTION

    oracle自治事务(Trigger)

    在触发器中使用自制事务及调用存储过程 Declare Pragma Autonomous_Transaction; ...

    oracle 存储过程学习

    快速学习函数创建和练习。 创建函数、存储过程、创建过程、调用存储过程、AUTHID、PRAGMA AUTONOMOUS_TRANSACTION、开发存储过程步骤、删除过程和函数、过程与函数的比较

    Oracle中怎样用自治事务保存日志表

    要创建一个自治事务,您必须在匿名块的最高层或者存储过程、函数、数据包或触发的定义部分中,使用PL/SQL中的PRAGMA AUTONOMOUS_TRANSACTION语句。在这样的模块或过程中执行的SQL Server语句都是自治的。

    利用pragma data_seg实现程序只能单个实例运行

    利用pragma data_seg实现程序只能单个实例运行测试工程。已在VC 6.0环境下成功运行

    SQLite 中文帮助pdf

    PRAGMA table_info('keys');--获取表的列信息 PRAGMA database_list; 对每个打开的数据库,使用该数据库的信息调用一次回叫函数。使用包括附加的数据库名和索引名在内的参数。第一行用于主数据库,第二行用于存放...

    #pragma用法_汇总.doc

    #pragma用法 汇总 doc 最近总有人问#pragma CODE SEG NEAR SEG NON BANKED 还有#pragma LINK INFO DERIVATIVE "mc9s12xs128"这些函数是什么意思 我在网上收集了一些资料希望能解大家疑惑 #pragma LINK ...

    oracle生成动态前缀且自增号码的函数分享

    代码如下:create or replace Function GetInvitationNO...– 需要使用“Current_User”的权限防止无法运行“Execute Immediate”命令 & “PRAGMA AUTONOMOUS_TRANSACTION”自制事务防止DML无法DDL的问题 Totalprev V

    #pragma_命令集合

    #pragma_命令集合 介绍pragma_命令的用法,使你不再迷茫

    pragma_comment用法

    pragma_comment用法,jian dan de jie shao.pragma_comment用法

    #pragma_命令集合.pdf

    #pragma_命令集合.pdf 不错的东西 很重要

    Oracle中大批量删除数据的方法

    create or replace procedure delBigTab(p_TableName in varchar2,p_Condition in varchar2,p_Count in varchar2) as pragma autonomous_transaction; n_delete number:=0; begin while 1=1 loop ...

    IAR软件的使用说明

    IAR软件的操作使用说明,非常详细,哈哈哈哈哈

    dsp28335开发总结

    1 #pragma CODE_SECTION(InitFlash, "ramfuncs")? 众所周知,微处理器从内存RAM中取指令的速度要比从flash中取指令要快好多倍,但是RAM的缺陷限制了其不能存储用户程序代码,因为RAM掉电会丢失数据,但是其速度要快...

    #pragma使用详解 .pdf

    #pragma使用详解 .pdf #pragma使用详解 .pdf #pragma使用详解 .pdf

    #Pragma_Pack.doc

    很详细的讲解 #Pragma_Pack的用法,作用,及效果,一目了然。

    Qt Sqlite加密数据库驱动源代码

    只不过对于加密数据库,需要在对数据库进行任何操作前,先执行“PRAGMA key=xxx;”。通过这种方式输入数据库密码。检验之前的密码是否正确可以在命令行中键入“.databases”,如果没有错误提示,那就是解密成功了;...

    SQLite PRAGMA

    SQLite PRAGMA SQLite 的 PRAGMA 命令是一个特殊的命令,可以用在 SQLite 环境内控制各种环境变量和状态标志。一个 PRAGMA 值可以被读取,也可以根据需求进行设置。 语法 要查询当前的 PRAGMA 值,只需要提供该 ...

    MFC 下获取键盘,鼠标的钩子程序

    #pragma data_seg("MySec") HWND g_hWnd=NULL; #pragma data_seg() #pragma comment(linker,"/section:MySec,RWS") /* SEGMENTS MySec READ WRITE SHARE */ #define WM_MSG WM_USER + 500 LRESULT CALLBACK ...

    解析#pragma指令

    在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的情况下,给出主机或...

Global site tag (gtag.js) - Google Analytics