Oracle与Postgresql在PLSQL内事务回滚的重大差异
2023-06-13 09:12:50 时间
相关 《Oracle/Mysql迁移到Postgresql事务回滚行为差异及改造方法》 《Oracle与Postgresql在PLSQL内事务回滚的重大差异》
这个差异点非常容易造成Oracle迁移到PG后业务逻辑出现重大差异。
1 总结
先放总结
- Oracle:在PLSQL内如果语句执行失败,进入异常处理程序后,PL程序正常退出。那么在执行失败语句前面的SQL
不会回滚
,执行结果都正常提交了。 - Postgresql:在PLPGSQL内如果语句执行失败,进入异常处理程序后,PL正常退出。
那么整个PL内的所有SQL自动回滚
,因为:- PG不支持PL内写SAVEPOINT (Oracle在每个语句前有隐式的savepoint)
- PL整体包装在一个大事务内。
Oracle11g
https://docs.oracle.com/cd/E11882_01/appdev.112/e25519/static.htm#LNPLS598
2 测试用例Oracle11g
drop table employees;
create table employees(employee_id int, salary int, raise int, job_id varchar(16), last_name varchar(16), first_name varchar(16));
insert into employees values (1, 1000, 60, 'ST_CLERK', 'Geller', 'Rose');
insert into employees values (2, 2000, 100, 'ST_CLERK', 'Green', 'Rachel');
insert into employees values (3, 4000, 400, 'ST_AAAAA', 'Bing', 'Chanller');
insert into employees values (4, 6000, 630, 'AD_CLERK', 'Geller', 'Rose');
insert into employees values (5, 7000, 120, 'AD_DSFWR', 'Green', 'Rachel');
insert into employees values (6, 8000, 410, 'AD_AAAAA', 'Bing', 'Chanller');
DROP TABLE emp_name;
CREATE TABLE emp_name AS SELECT employee_id, last_name, salary FROM employees;
CREATE UNIQUE INDEX empname_ix ON emp_name (employee_id);
DECLARE
emp_id employees.employee_id%TYPE;
emp_lastname employees.last_name%TYPE;
emp_salary employees.salary%TYPE;
BEGIN
SELECT employee_id, last_name, salary
INTO emp_id, emp_lastname, emp_salary
FROM employees
WHERE employee_id = 1;
INSERT INTO emp_name (employee_id, last_name, salary) VALUES (100, emp_lastname, emp_salary);
INSERT INTO emp_name (employee_id, last_name, salary) VALUES (emp_id, emp_lastname, emp_salary);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
DBMS_OUTPUT.PUT_LINE('Insert was rolled back');
END;
/
select * from emp_name;
结果
3 测试用例Postgresql14
drop table employees;
create table employees(employee_id int, salary int, raise int, job_id varchar(16), last_name varchar(16), first_name varchar(16));
insert into employees values (1, 1000, 60, 'ST_CLERK', 'Geller', 'Rose');
insert into employees values (2, 2000, 100, 'ST_CLERK', 'Green', 'Rachel');
insert into employees values (3, 4000, 400, 'ST_AAAAA', 'Bing', 'Chanller');
insert into employees values (4, 6000, 630, 'AD_CLERK', 'Geller', 'Rose');
insert into employees values (5, 7000, 120, 'AD_DSFWR', 'Green', 'Rachel');
insert into employees values (6, 8000, 410, 'AD_AAAAA', 'Bing', 'Chanller');
DROP TABLE emp_name;
CREATE TABLE emp_name AS SELECT employee_id, last_name, salary FROM employees;
CREATE UNIQUE INDEX empname_ix ON emp_name (employee_id);
select * from emp_name;
DO $$DECLARE
emp_id employees.employee_id%TYPE;
emp_lastname employees.last_name%TYPE;
emp_salary employees.salary%TYPE;
BEGIN
SELECT employee_id, last_name, salary
INTO emp_id, emp_lastname, emp_salary
FROM employees
WHERE employee_id = 1;
INSERT INTO emp_name (employee_id, last_name, salary) VALUES (100, emp_lastname, emp_salary);
INSERT INTO emp_name (employee_id, last_name, salary) VALUES (emp_id, emp_lastname, emp_salary);
EXCEPTION
WHEN others THEN
raise notice 'Insert was rolled back';
END$$;
select * from emp_name;
执行结果
相关文章
- 行深入浅出:Oracle数据命令行操作指南(oracle数据命令)
- 一步一步轻松卸载Linux上的Oracle(linux卸载oracle)
- Oracle事务处理: 理解与使用SQL语句(oracle事务语句)
- 使用Oracle数据库删除用户(oracle数据库删除用户)
- 深入了解Oracle分布式事务机制,优化多节点系统并确保数据一致性(oracle分布式事务)
- Troubleshooting Oracle: Investigating Uncommitted Transactions(oracle未提交事务)
- 错误Oracle数据库的或取值错误处理方法(oracle 或取值)
- 利用Oracle过程进行多步骤事务处理(oracle 过程事务)
- Oracle 回滚事务:保护数据安全(oracle 回滚事务)
- EF连接Oracle 解决闪退之路(ef连接oracle闪退)
- 里Oracle主目录在哪里(oracle 主目录在那)
- 利用Oracle事务回滚命令实现数据安全(oracle事物回滚命令)
- 如何撤销Oracle数据库中的事务(oracle事务撤销)
- Oracle事务嵌套中的回滚策略(oracle事务嵌套回滚)
- Oracle 修复安装,完美恢复(oracle 修复安装)
- Oracle事务的回滚机制实现(oracle事务回滚方式)
- Oracle事务实现四大特性的基石(oracle事务四大特性)
- 用Oracle代码生成工具轻松实现开发梦想(oracle代码生成工具)
- Oracle中组合两个字段的应用(oracle两个字段组合)
- Oracle任重而道远,不够的补0(oracle 不够的补0)
- Oracle 数据库中一行字段大小优化指南(oracle一行字段大小)