您好,我是小DAI,专注于数据库管理员相关的技术问答,请问有什么可以帮您?

自主事务

语法:

 :: = BEGIN AUTONOMOUS TRANSACTION 

[]

[]

[]

END;

描述:

自主事务独立于主过程。自主事务进行和提交的更改可以存储在持久性中,而不考虑主过程事务的提交/回滚。自主事务块的结束具有隐式提交。

BEGIN AUTONOMOUS TRANSACTION 

…(some updates) –(1)

COMMIT;

…(some updates) –(2)

ROLLBACK;

…(some updates) –(3)

END;

这些示例显示了在自主事务块内如何执行提交和回滚。提交第一个更新 (1),从而完全回滚步骤 (2) 中进行的更新。最后更新 (3) 由自主块末尾的隐式提交提交。

CREATE PROCEDURE PROC1( IN p INT , OUT outtab TABLE (A INT)) LANGUAGE SQLSCRIPT AS  

BEGIN

DECLARE errCode INT;

DECLARE errMsg VARCHAR(5000);

DECLARE EXIT HANDLER FOR SQLEXCEPTION

BEGIN AUTONOMOUS TRANSACTION

errCode= ::SQL_ERROR_CODE;

errMsg= ::SQL_ERROR_MESSAGE ;

INSERT INTO ERR_TABLE (PARAMETER,SQL_ERROR_CODE, SQL_ERROR_MESSAGE)

VALUES ( :p, :errCode, :errMsg);

END;

outtab = SELECT 1/:p as A FROM DUMMY; -- DIVIDE BY ZERO Error if p=0

END

在上面的示例中,自治事务用于将 ERR_TABLE 中的错误代码保持在持久性中。

如果异常处理器块不是自主事务,则将回退每个插入,因为它们都在主事务中进行。在这种情况下,ERR_TABLE 的结果如下例所示。

P |SQL_ERROR_CODE| SQL_ERROR_MESSAGE

0 | 304 | division by zero undefined: at function /()

也可以有嵌套的自主事务。

CREATE PROCEDURE P2()

AS BEGIN

BEGIN AUTONOMOUS TRANSACTION

INSERT INTO LOG_TABLE VALUES ('MESSAGE');

BEGIN AUTONOMOUS TRANSACTION

ROLLBACK;

END;

END;

END;

LOG_TABLE 表包含 'MESSAGE',即使内部自主事务已回退。

块内支持的语句

  • SELECTINSERTDELETEUPDATE 、 UPSERT 、 REPLACE

  • IFWHILEFORBEGIN/END

  • COMMITROLLBACK、RESIGNAL、SIGNAL

  • 标量变量赋值

    块内不支持的语句

  • 调用其它过程

  • DDL

  • 光标

  • 表分配

    备注如果在嵌套过程(例如TRUNCATE,更新同一行),因为这可能导致死锁情况。避免这种情况的一种解决方案是,在嵌套过程中进入自主事务之前提交更改。