DBMS_TRANSACTION

DBMS_TRANSACTION是一个兼容Oracle语法的内置包,用于在PL/SQL程序块(如存储过程、函数)中实现对事务的精细化控制。当您需要在一段复杂的业务逻辑中撤销部分操作而非回滚整个事务时,可以使用该包提供的保存点(Savepoint)功能,实现更灵活的事务管理。

功能简介

PolarDB PostgreSQL版(兼容Oracle)支持以下四个函数:

  • SAVEPOINT:标记事务中的保存点,用于回滚到指定保存点。

  • ROLLBACK_SAVEPOINT:回滚到指定保存点,用于撤销保存点后的操作。

  • COMMIT:提交当前事务,用于永久化更改数据。

  • ROLLBACK:回滚整个事务,用于撤销所有未提交的操作。

前提条件

仅支持Oracle语法兼容 2.0,且内核小版本需为2.0.14.17.34.0及以上版本。

说明

您可在控制台查看内核小版本号,也可以通过SHOW polardb_version;语句查看。如未满足内核小版本要求,请升级内核小版本

注意事项

  • 使用SAVEPOINTROLLBACK_SAVEPOINT前,请先开启polar_default_pl_stmt_transaction_rollback参数。

  • COMMITROLLBACK会结束当前事务,如需继续使用,需重新开始新事务。

  • 频繁使用SAVEPOINT可能会增加事务开销,建议合理规划事务的粒度。

  • 不支持BEGIN_WORKSET_TRANSACTION等高级功能。

  • EXECUTE IMMEDIATE场景中,若需使用COMMIT/ROLLBACK,请先开启polar_enable_commit_in_execute_immediate参数。

SAVEPOINT

在事务中设置保存点(Savepoint),用于后续回滚到该点。

语法

DBMS_TRANSACTION.SAVEPOINT(savepoint_name VARCHAR2);

参数说明

参数

描述

savepoint_name

保存点的名称。

示例

DECLARE
BEGIN
    -- 插入测试数据
    INSERT INTO test_table (id, name) VALUES (1, 'Alice');

    -- 设置保存点
    DBMS_TRANSACTION.SAVEPOINT('sp1');

    -- 执行可能失败的操作
    INSERT INTO test_table (id, name) VALUES (2, 'Bob');

    -- 提交事务
    COMMIT;
END;
说明
  1. 事务开始后,插入一条数据,并记录保存点sp1。

  2. 若后续操作失败,可通过ROLLBACK_SAVEPOINT回滚到sp1。

  3. 最后COMMIT提交事务,所有更改生效。

ROLLBACK_SAVEPOINT

回滚事务到指定保存点(Savepoint),撤销保存点之后的操作。

语法

DBMS_TRANSACTION.ROLLBACK_SAVEPOINT(savepoint_name VARCHAR2);

参数说明

参数

描述

savepoint_name

保存点的名称。

示例

DECLARE
BEGIN
    -- 插入第一条记录
    INSERT INTO test_table (id, name) VALUES (1, 'Alice');

    -- 设置保存点
    DBMS_TRANSACTION.SAVEPOINT('sp1');

    -- 插入第二条记录(可能失败)
    INSERT INTO test_table (id, name) VALUES (2, 'Bob');

    -- 回滚到保存点 sp1
    DBMS_TRANSACTION.ROLLBACK_SAVEPOINT('sp1');

    -- 提交事务
    COMMIT;
END;
说明
  1. 事务开始后,插入一条数据Alice,并记录保存点sp1。

  2. 插入第二条数据,并通过ROLLBACK_SAVEPOINT('sp1')回滚,Bob的记录不会被保留。

  3. 最后COMMIT提交事务,仅保留了Alice的插入数据。

COMMIT

提交当前事务,使所有更改永久生效。

语法

DBMS_TRANSACTION.COMMIT();

示例

DECLARE
BEGIN
    -- 插入两条记录
    INSERT INTO test_table (id, name) VALUES (1, 'Alice');
    INSERT INTO test_table (id, name) VALUES (2, 'Bob');

    -- 提交事务
    DBMS_TRANSACTION.COMMIT();
END;
说明
  1. 事务开始后,插入两条数据。

  2. 调用COMMIT提交事务。所有更改将被永久写入数据库。

  3. 若未显式提交,事务在程序块结束时自动提交(取决于数据库配置)。

ROLLBACK

回滚整个事务,撤销所有未提交的更改。

语法

DBMS_TRANSACTION.ROLLBACK();

示例

DECLARE
BEGIN
    -- 插入第一条记录
    INSERT INTO test_table (id, name) VALUES (1, 'Alice');

    -- 模拟错误
    IF 1 = 1 THEN
        RAISE_APPLICATION_ERROR(-20001, '人为触发错误');
    END IF;

    -- 提交事务(不会执行)
    DBMS_TRANSACTION.COMMIT();
EXCEPTION
    WHEN OTHERS THEN
        -- 回滚整个事务
        DBMS_TRANSACTION.ROLLBACK();
        DBMS_OUTPUT.PUT_LINE('事务已回滚');
END;
说明
  1. 事务开始后,插入一条数据Alice后,触发人为错误。

  2. 在异常处理EXCEPTION中调用ROLLBACK(),撤销所有未提交的更改。

  3. 最后事务被回滚,test_table中无新增记录。