【DB吐槽大会】第67期 - PG 存储过程和函数内对自治事务支持不完整

本文涉及的产品
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
简介: 大家好,这里是DB吐槽大会,第67期 - PG 存储过程和函数内对自治事务支持不完整

背景


1、产品的问题点

  • PG 存储过程和函数内对自治事务支持不完整

2、问题点背后涉及的技术原理

  • PG 的1个函数为1个原子操作, 要么全部回滚, 要么全部失败. (注意: exception里算一个新事务, 触发exception时, 函数体内的操作全部回滚, exception体内的执行如果正常则这个exception体内的变更操作可以提交.)
  • 在函数内不能使用commit, rollback, savepoint等事务控制语句.
  • 在存储过程中只能使用commit, rollback事务控制语句, 不能使用savepoint, rollback to savepoint, release savepoint等语句.

3、这个问题将影响哪些行业以及业务场景

  • 使用function, procedure进行复杂业务逻辑处理的场景, 例如分析业务, 报表业务等

4、会导致什么问题?

  • 无法灵活的处理事务控制

5、业务上应该如何避免这个坑

  • 暂时没有很好的解决方案, 一些类似的替代方案, 都非常难操作

使用exception也很难满足, 如下, 使用变量、exception 来模拟savepoint和rollback to savepoint的功能, 也很复杂 :

create or replace procedure p (int, int) as $$  
declare  
  v int := $1;  
  retris int := $2;  
  text_var1 text;  
  text_var2 text;  
  text_var3 text;  
  text_var4 text;  
begin  
  if retris >= 3 then   
    raise notice 'retris: %', retris;   
    return;   
  end if;    
  if v = 0 then  
    v := 1;  
    insert into a values (1);   
    commit;  
  end if;  
  if v = 1 then   
    v := 2;  
    insert into a values (2);  
    commit;  
  end if;   
  if v = 2 then   
    v := 3;   
    insert into a values (3);   
    commit;   
  end if;   
  if v = 3 then   
    v := 4;   
    insert into a values (4);   
    commit;   
  end if;   
exception when others then   
  GET STACKED DIAGNOSTICS text_var1 = MESSAGE_TEXT,  
                          text_var2 = PG_EXCEPTION_DETAIL,  
                          text_var3 = PG_EXCEPTION_HINT,  
                          text_var4 = PG_EXCEPTION_CONTEXT;  
                          raise notice '%,%,%,%', text_var1, text_var2, text_var3, text_var4;  
  commit;  
  call p(v-1, retris+1) ;   
end;   
$$ language plpgsql;   
postgres=# \set VERBOSITY verbose  
postgres=# call p (0,0);  
NOTICE:  00000: cannot commit while a subtransaction is active,,,PL/pgSQL function p(integer,integer) line 18 at COMMIT  
LOCATION:  exec_stmt_raise, pl_exec.c:3906  
NOTICE:  00000: cannot commit while a subtransaction is active,,,PL/pgSQL function p(integer,integer) line 18 at COMMIT  
SQL statement "call p(v-1, retris+1)"  
PL/pgSQL function p(integer,integer) line 45 at CALL  
LOCATION:  exec_stmt_raise, pl_exec.c:3906  
NOTICE:  00000: cannot commit while a subtransaction is active,,,PL/pgSQL function p(integer,integer) line 18 at COMMIT  
SQL statement "call p(v-1, retris+1)"  
PL/pgSQL function p(integer,integer) line 45 at CALL  
SQL statement "call p(v-1, retris+1)"  
PL/pgSQL function p(integer,integer) line 45 at CALL  
LOCATION:  exec_stmt_raise, pl_exec.c:3906  
NOTICE:  00000: retris: 3  
LOCATION:  exec_stmt_raise, pl_exec.c:3906  
CALL  
通过dblink去调用p(int,int), 开启一个新会话是可以的. 复杂度又增加了.    

6、业务上避免这个坑牺牲了什么, 会引入什么新的问题

  • 开发门槛非常高.

7、数据库未来产品迭代如何修复这个坑

  • 希望在函数、存储过程中实现完整的事务控制逻辑. 包括begin;end;savepoint;rollback;commit;release savepoint;rollback to savepoint;等
相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
6月前
|
存储 SQL NoSQL
mysql存储过程和存储函数
mysql存储过程和存储函数
|
5月前
|
存储 关系型数据库 MySQL
MySql创建带事务操作的存储过程
MySql创建带事务操作的存储过程
|
5月前
|
存储 SQL 关系型数据库
MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】(2)
MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】
|
5月前
|
存储 SQL 关系型数据库
MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】(1)
MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】
|
4月前
|
存储 SQL 数据库
MySQL设计规约问题之为什么要避免使用存储过程、触发器和函数
MySQL设计规约问题之为什么要避免使用存储过程、触发器和函数
|
5月前
|
存储 SQL 关系型数据库
MySQL存储过程和存储函数的使用
MySQL的存储过程和存储函数在功能和用法上有明显的区别。存储过程是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,通过指定名称和参数(如果有)来调用执行,可以返回多个值或结果集,但不直接返回值。而存储函数则是一个有返回值的特殊存储过程,它返回一个值或表对象,可以直接嵌入SQL语句中使用,如SELECT语句中。两者都是为了提高SQL代码的重用性和性能,但使用场景和方式有所不同。
4296 4
|
5月前
|
存储 SQL 关系型数据库
MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】(3)
MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】
|
5月前
|
存储 关系型数据库 MySQL
MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】(4)
MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】
|
6月前
|
存储 SQL Oracle
02-PostgreSQL 存储过程的进阶介绍(含游标、错误处理、自定义函数、事务)
02-PostgreSQL 存储过程的进阶介绍(含游标、错误处理、自定义函数、事务)
|
6月前
|
存储 SQL 关系型数据库
Msql第四天,存储过程和函数
Msql第四天,存储过程和函数
71 0
Msql第四天,存储过程和函数
下一篇
无影云桌面