Oracle PL/SQL 中的自治事务:Commit、Rollback
PL/SQL 中的 TCL 语句是什么?
TCL 代表事务控制语句。它将保存待处理的事务或回滚待处理的事务。这些语句发挥着至关重要的作用,因为除非事务被保存,否则通过 DML 语句所做的更改将不会保存在数据库中。以下是不同的 TCL 语句。
COMMIT | 保存所有待处理的事务 |
ROLLBACK | 放弃所有待处理的事务 |
SAVEPOINT | 在事务中创建一个点,之后可以回滚到该点 |
ROLLBACK TO | 放弃到指定 <保存点> 的所有待处理事务 |
在以下情况下,事务将完成。
- 发出以上任一语句时(SAVEPOINT 除外)
- 发出 DDL 语句时。(DDL 是自动提交语句)
- 发出 DCL 语句时。(DCL 是自动提交语句)
什么是自治事务
在 PL/SQL 中,所有对数据的修改都称为事务。当对事务应用保存/放弃时,该事务被视为已完成。如果未提供保存/放弃,则事务不会被视为已完成,并且对数据所做的修改不会在服务器上永久生效。
无论会话中进行了哪些修改,PL/SQL 都会将整个修改视为一个单独的事务,对其进行保存/放弃会影响该会话中的所有待处理更改。自治事务为开发人员提供了一种功能,允许他们在单独的事务中进行更改,并保存/放弃该特定事务,而不会影响主会话事务。
- 此自治事务可以在子程序级别指定。
- 要使任何子程序在不同的事务中工作,应在块的声明部分给出关键字“PRAGMA AUTONOMOUS_TRANSATION”。
- 这将指示编译器将其视为单独的事务,并且在此块内的保存/放弃不会反映在主事务中。
- 在离开此自治事务进入主事务之前,必须发出 COMMIT 或 ROLLBACK,因为任何时候只能激活一个事务。
- 因此,一旦我们进行了自治事务,我们就需要保存它并完成事务,然后才能返回主事务。
语法
DECLARE PRAGMA AUTONOMOUS_TRANSACTION; . BEGIN <executin_part> [COMMIT|ROLLBACK] END; /
- 在上述语法中,该块已成为自治事务。
示例 1:在此示例中,我们将了解自治事务是如何工作的。
DECLARE l_salary NUMBER; PROCEDURE nested_block IS PRAGMA autonomous_transaction; BEGIN UPDATE emp SET salary = salary + 15000 WHERE emp_no = 1002; COMMIT; END; BEGIN SELECT salary INTO l_salary FROM emp WHERE emp_no = 1001; dbms_output.put_line('Before Salary of 1001 is'|| l_salary); SELECT salary INTO l_salary FROM emp WHERE emp_no = 1002; dbms_output.put_line('Before Salary of 1002 is'|| l_salary); UPDATE emp SET salary = salary + 5000 WHERE emp_no = 1001; nested_block; ROLLBACK; SELECT salary INTO l_salary FROM emp WHERE emp_no = 1001; dbms_output.put_line('After Salary of 1001 is'|| l_salary); SELECT salary INTO l_salary FROM emp WHERE emp_no = 1002; dbms_output.put_line('After Salary of 1002 is '|| l_salary); end;
输出
Before:Salary of 1001 is 15000 Before:Salary of 1002 is 10000 After:Salary of 1001 is 15000 After:Salary of 1002 is 25000
代码解释
- 代码第 2 行:声明 l_salary 为 NUMBER。
- 代码第 3 行:声明 nested_block 过程
- 代码第 4 行:将 nested_block 过程设置为“AUTONOMOUS_TRANSATION”。
- 代码第 7-9 行:将员工编号 1002 的工资增加 15000。
- 代码第 10 行:提交事务。
- 代码第 13-16 行:打印更改前员工 1001 和 1002 的工资详情。
- 代码第 17-19 行:将员工编号 1001 的工资增加 5000。
- 代码第 20 行:调用 nested_block 过程;
- 代码第 21 行:放弃主事务。
- 代码第 22-25 行:打印更改后员工 1001 和 1002 的工资详情。
- 员工 1001 的工资增加未被反映,因为主事务已被放弃。员工 1002 的工资增加被反映出来,因为该块已作为单独的事务创建并在最后保存。
- 因此,无论主事务如何保存/放弃,自治事务中的更改都会被保存,而不会影响主事务的更改。