前言

本文介绍游标在PLSQL和SQL层跨事务使用案例,及其案例一则。

本文验证版本:

db0=# select version();
db0-# /
version ---------------------------------------- KingbaseES V008R006C007B0024 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-28), 64-bit
(1 row)

一,PLSQL块中的游标跨事务

原生plpgsql跨事务例子,不支持跨事务

drop table t2;

create table t2(id int,name varchar(20));
insert into t2 values (1,'aaa'), (2,'bbb'), (3,'ccc');
create or replace procedure testcur02
as
$$
declare
cur1 refcursor;
vid numeric;
vname varchar(20);
begin
open cur1 for select * from t2;
commit;
fetch cur1 into vid,vname; --因为cur1在commit后被自动释放,所以将报错不存在
raise notice 'vid:%,vname:%',vid,vname;
close cur1;
end;
$$ language plpgsql; call testcur02(); --运行结果
db0=# call testcur02();
db0-#
db0-# /
error: cursor "<unnamed portal 8>" does not exist
context: pl/pgsql function testcur02() line 9 at fetch

kes-plsql默认支持存储过程中跨事务

drop table t2;

create table t2(id int,name varchar(20));
insert into t2 values (1,'aaa'), (2,'bbb'), (3,'ccc');
create or replace procedure testcur01
is
declare
cur1 refcursor;
vid numeric;
vname varchar(20);
begin
open cur1 for select * from t2;
commit;
fetch cur1 into vid,vname; --cur1在commit后不会被自动释放
raise notice 'vid:%,vname:%',vid,vname;
close cur1;
end; call testcur01(); --运行结果
db0=# call testcur01();
db0-# /
notice: vid:1,vname:aaa
call
db0=#

二,SQL层的游标和事务

SQL层也有游标语句,也可声明游标,为了验证跨事务问题,以fetch all in语句为例。

create or replace procedure testcur04( pcur1 out refcursor)
is
begin
open pcur1 for select * from t2;
end; db0=# begin; ---开启事务
db0-# /
BEGIN
db0=# call testcur04('vcur'); ----获取游标结果集
db0-# / pcur1
------- vcur
(1 row) db0=# fetch all in vcur; ---一次性提取游标结果集
db0-# /
id | name
----+------
1 | aaa
2 | bbb
3 | ccc
(3 rows) db0=#

在早前的V7版本,可以通过开启 enable_out_refcursor_holdable 参数为on,

实现在SQL层跨事务执行上述游标结果集(要求存储过程的参数模式为out 或inout),目前实测来看V008R006C007B0024已不支持该参数。

三,游标跨事务案例一则

这是一个V7版本上产生的问题,

问题描述客户应用层代码使用fetch al in获取游标结果集,但是报错游标不存在。完整的截取客户代码如下;

[2023-07-07 09:56:20.605 CST] [192.1.153.142][192.1.153.142(49637)][EMS][34][D5000][0]LOG: statement: SELECT nspname, proname, proretset, prorettypedef, pronargs, proargtypes, protype, proargnames, proargmodes, proargtypmods FROM sys_catalog.sys_namespace JOIN sys_catalog.sys_proc on sys_proc.pronamespace = sys_namespace.oid AND (not proretset) AND nspname NOT LIKE 'SYS_%' ESCAPE '' AND nspname != 'INFORMATION_SCHEMA' LEFT JOIN sys_catalog.sys_package ON sys_proc.propkgoid = sys_package.oid AND sys_package.pkgnamespace = sys_namespace.oid WHERE 1 AND proname LIKE 'PROC_KBV7_OCI_0X1794F90' ESCAPE '' ORDER BY nspname, proname, proretset

---第一段黑体字

[2023-07-07 09:56:20.607 CST] [192.1.153.142][192.1.153.142(49637)][EMS][34][D5000][0]LOG: statement: SET ENABLE_OUT_REFCURSOR_HOLDABLE TO on

[2023-07-07 09:56:20.608 CST] [192.1.153.142][192.1.153.142(49637)][EMS][34][D5000][0]LOG: statement: call PROC_KBV7_OCI_0x1794f90('KDBCUR_178A2F0_0')

[2023-07-07 09:56:20.609 CST] [192.1.153.142][192.1.153.142(49637)][EMS][34][D5000][0]LOG: statement: fetch all in KDBCUR_178A2F0_0

[2023-07-07 09:56:20.609 CST] [192.1.153.142][192.1.153.142(49637)][EMS][34][D5000][0]LOG: statement: drop procedure if exists PROC_KBV7_OCI_0x1794f90(REFCURSOR)

[2023-07-07 09:56:20.611 CST] [192.1.153.142][192.1.153.142(49637)][EMS][34][D5000][0]LOG: statement: close KDBCUR_178A2F0_0


[2023-07-07 09:56:20.613 CST] [192.1.153.142][192.1.153.142(49637)][EMS][34][D5000][0]LOG: parse _PLAN0X178D4B0: select object_name from user_objects where object_name = 'TRIGGER_PKG' and (object_type = 'PACKAGE' or object_type = 'PACKAGE BODY') and status<>'VALID'

[2023-07-07 09:56:20.616 CST] [192.1.153.142][192.1.153.142(49637)][EMS][34][D5000][0]LOG: statement: EXECUTE _PLAN0x178d4b0()

[2023-07-07 09:56:20.616 CST] [192.1.153.142][192.1.153.142(49637)][EMS][34][D5000][0]DETAIL: prepare: select object_name from user_objects where object_name = 'TRIGGER_PKG' and (object_type = 'PACKAGE' or object_type = 'PACKAGE BODY') and status<>'VALID'

[2023-07-07 09:56:20.623 CST] [192.1.153.142][192.1.153.142(49637)][EMS][34][D5000][0]LOG: close _PLAN0X178D4B0

[2023-07-07 09:56:20.624 CST] [192.1.153.142][192.1.153.142(49637)][EMS][34][D5000][0]LOG: statement: SELECT PRONAME, PROTYPE FROM SYS_PROC, SYS_PACKAGE WHERE SYS_PROC.PROPKGOID = SYS_PACKAGE.OID AND PKGNAME = UPPER('TRIGGER_PKG');

[2023-07-07 09:56:20.626 CST] [192.1.153.142][192.1.153.142(49637)][EMS][34][D5000][0]LOG: statement: SELECT nspname, proname, proretset, prorettypedef, pronargs, proargtypes, protype, proargnames, proargmodes, proargtypmods FROM sys_catalog.sys_namespace JOIN sys_catalog.sys_proc on sys_proc.pronamespace = sys_namespace.oid AND (not proretset) AND nspname NOT LIKE 'SYS_%' ESCAPE '' AND nspname != 'INFORMATION_SCHEMA' LEFT JOIN sys_catalog.sys_package ON sys_proc.propkgoid = sys_package.oid AND sys_package.pkgnamespace = sys_namespace.oid WHERE 1 AND pkgname LIKE UPPER('TRIGGER_PKG') ESCAPE '' AND proname LIKE UPPER('SELECT_TRIGGER_ACTIONS') ESCAPE '' ORDER BY nspname, proname, proretset

[2023-07-07 09:56:20.628 CST] [192.1.153.142][192.1.153.142(49637)][EMS][34][D5000][0]LOG: statement: CREATE OR REPLACE PROCEDURE PROC_KBV7_OCI_0x1786320(INTERNAL_PREFIX_0 INOUT REFCURSOR)

AS

begin TRIGGER_PKG.select_trigger_actions(INTERNAL_PREFIX_0); end;

[2023-07-07 09:56:20.631 CST] [192.1.153.142][192.1.153.142(49637)][EMS][34][D5000][0]LOG: statement: SELECT nspname, proname, proretset, prorettypedef, pronargs, proargtypes, protype, proargnames, proargmodes, proargtypmods FROM sys_catalog.sys_namespace JOIN sys_catalog.sys_proc on sys_proc.pronamespace = sys_namespace.oid AND (not proretset) AND nspname NOT LIKE 'SYS_%' ESCAPE '' AND nspname != 'INFORMATION_SCHEMA' LEFT JOIN sys_catalog.sys_package ON sys_proc.propkgoid = sys_package.oid AND sys_package.pkgnamespace = sys_namespace.oid WHERE 1 AND proname LIKE 'PROC_KBV7_OCI_0X1786320' ESCAPE '' ORDER BY nspname, proname, proretset

---第二段黑体字

[2023-07-07 09:56:20.633 CST] [192.1.153.142][192.1.153.142(49637)][EMS][34][D5000][0]LOG: statement: call PROC_KBV7_OCI_0x1786320('KDBCUR_1789020_1')

[2023-07-07 09:56:20.634 CST] [192.1.153.142][192.1.153.142(49637)][EMS][34][D5000][0]LOG: statement: fetch all in KDBCUR_1789020_1

2023-07-07 09:56:20.634 CST] [192.1.153.142][192.1.153.142(49637)][EMS][34][D5000][0]ERROR: cursor "KDBCUR_1789020_1" does not exist

[2023-07-07 09:56:20.634 CST] [192.1.153.142][192.1.153.142(49637)][EMS][34][D5000][0]STATEMENT: fetch all in KDBCUR_1789020_1

[2023-07-07 09:56:20.635 CST] [192.1.153.142][192.1.153.142(49637)][EMS][34][D5000][0]LOG: statement: drop procedure if exists PROC_KBV7_OCI_0x1786320(REFCURSOR)

[2023-07-07 09:56:20.636 CST] [192.1.153.142][192.1.153.142(49637)][EMS][34][D5000][0]LOG: statement: close KDBCUR_1789020_1

[2023-07-07 09:56:20.636 CST] [192.1.153.142][192.1.153.142(49637)][EMS][34][D5000][0]ERROR: cursor "KDBCUR_1789020_1" does not exist

从上面第一段黑体的日志可以看出,SET ENABLE_OUT_REFCURSOR_HOLDABLE TO on使游标可以跨事务执行,并且fetch all in KDBCUR_178A2F0_0执行游标提取成功,但是在第二段日志中同样的操作却出现了报错“ cursor "KDBCUR_1789020_1" does not exist”问题。

通过自己编写缩小的案例实测:

create or replace procedure proc_test01 (
pcur inout refcursor
)
as
begin
open for select * from t1;
end ; SET ENABLE_OUT_REFCURSOR_HOLDABLE TO on; CALL PROC_TEST01('KDBCUR') fetch all in KDBCUR

以上以上代码是能获取到结果集,但是必须要求proc_test01的参数为inout或者out模式,最终通过追查客户PROC_KBV7_OCI_0x1786320存储过程的定义,发现其未将参数模式定位为inout或者out模式,而是IN模式,故而问题找到原因。

Kingbase ES 游标跨事务及其案例一则的更多相关文章

  1. Kingbase V8R6集群安装部署案例---脚本在线一键缩容

    ​ 案例说明: KingbaseES V8R6支持图形化方式在线缩容,但是在一些生产环境,在服务器不支持图形化界面的情况下 ,只能通过脚本命令行的方式执行集群的部署或在线缩容. Tips: Kingb ...

  2. Kingbase V8R6集群安装部署案例---脚本在线一键扩容

    案例说明: KingbaseES V8R6支持图形化方式在线扩容,但是在一些生产环境,在服务器不支持图形化界面的情况下 ,只能通过脚本命令行的方式执行集群的部署或在线扩容. Tips: Kingbas ...

  3. AngularJs最简单解决跨域问题案例

    AngularJs最简单解决跨域问题案例 2016-05-20 09:18 82人阅读 评论(0) 收藏 举报  分类: javascript(1)  作者:白狼 出处:http://www.mank ...

  4. MySql 中游标,事务,终止存储过程方法总结

    最近在项目开发中,有段逻辑处理,需要在网站,app,后台分别运行,这样给后期的维护带来了很大的不方便,容易遗漏app端或者后台,所以讲java代码转换成存储过程,把逻辑处理写在了mysql端,其中遇到 ...

  5. ES scroll(ES游标) 解决深分页

    ES scroll(ES游标) 解决深分页. Why 当Elasticsearch响应请求时,它必须确定docs的顺序,排列响应结果.如果请求的页数较少(假设每页20个docs), Elasticse ...

  6. ES Bridge跨链桥服务升级,新增BSC跨链网络

    3月15日,Equal Sign Bridge(ES Bridge)跨链桥宣布新增BSC跨链网络,方便更多用户参与到ES Bridge的建设与发展,未来还将持续拓展更多的主流跨链币种,提升各链间的互操 ...

  7. Spring+Mybatis+MySql+Maven 简单的事务管理案例

    利用Maven来管理项目中的JAR包,同时使用Spring在业务处理层进行事务管理.数据库使用MySq,数据处理层使用Spring和Mybatis结合. 本案例代码主要结构如图: 1.数据库脚本 -- ...

  8. Hibernate中事务小案例

    理论知识: 什么是事务? 指作为单个逻辑工作单位执行的一系列操作,要么完全的执行,要么完全不执行.事务处理可以确保非事务性单元内的所有操作都完全完成,否则永久不会更新面向数据的资源.通过将一组操作组合 ...

  9. 跨域的案例 以百度接口/手写接口为例,还有jQuery写法

    仅在js部分输入即可 百度接口的案例 <script> function fn(data){ console.log(data) } </script> <script ...

  10. Spring 事务管理案例

    事务管理简介   Spring 事务管理有两种方式:一种是编程式事务管理,即通过编写代码实现事物管理,包括定义事务的开始,程序正常执行后的事物提交,异常时进行的事务回滚.另一种是基于AOP技术实现的声 ...

随机推荐

  1. 【OpenGL ES】纹理贴图

    1 前言 ​ 纹理贴图是指:将图片贴在模型的表面. ​ 纹理贴图的本质是:将图片划分为一系列三角形,使得图片顶点序列与模型顶点序列中的顶点一一对应,对于模型中任意三角形内部的坐标和图片中对应三角形内部 ...

  2. Js中数组空位问题

    Js中数组空位问题 JavaScript中数组空位指的是数组中的empty,其表示的是在该位置没有任何值,而且empty是区别于undefined的,同样empty也不属于Js的任何数据类型,并且在J ...

  3. java generic 介绍

    一 介绍: 在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的"任意化","任意化"带来的缺点是要做显式的强制类型转换, ...

  4. 在Mac下使用zsh

    什么是zsh 简单来说,zsh是一个构建于bash之上的shell工具,详见:zsh . 相比起bash,zsh默认支持许多非常实用的功能,比如:可以显示当前所在的git分支,这对于程序员来说是非常有 ...

  5. Docker实践之07-数据管理

    目录 一.数据卷概述 二.创建数据卷 三.查看数据卷 四.挂载数据卷 五.删除数据卷 六.挂载主机目录或文件 七.挂载数据卷与主机目录/文件的比较 一.数据卷概述 数据卷是一个可供一个或多个容器使用的 ...

  6. java数组实现的超市管理系统(控制台)

    说明:使用数组存储数据,针对用户功能1:增加用户2:删除用户3:修改用户:针对商品功能:1.显示所有商品2.修改商品信息3.添加商品信息4.删除商品信息5.查询商品信息 效果展示 ========== ...

  7. 【Azure 存储服务】多设备并发往 Azure Storage Blob 的 Container 存数据是否可以

    问题描述 多设备并发往 Azure Storage Blob 的 Container 存数据是否可以? 问题解答 可以! Azure Storage 是支持的并发存储数据的,Blob 可以使用乐观并发 ...

  8. MySQL日志15连问,redo log与biglog

    1. redo log是什么? 为什么需要redo log? redo log 是什么呢? redo log 是重做日志. 它记录了数据页上的改动. 它指事务中修改了的数据,将会备份存储. 发生数据库 ...

  9. jQuery 框架

    jQuery 框架 目录 jQuery 框架 一. 概述 二. jQuery 安装引用 2.1 安装 2.2 本地导入使用 2.3 jQuery CDN引入 三. jQuery基本语法 四. 查找标签 ...

  10. Mysql 增删改查语言系列

    Mysql 数据语言系列 目录 Mysql 数据语言系列 一.数据定义语言 DDL 1 数据库规范 2 DDL 语言使用 2 创建视图 二. 数据操纵语言 DML 1 插入语法 2 更新语法 3 删除 ...