ORACLE报错:ORA-04091 表XXX发生了变化,触发器/函数不能读它

ORACLE报错:ORA-04091 表发XXX生了变化,触发器/函数不能读它

  • 问题描述
  • 问题分析
  • 解决办法
  • 拓展:自治事务的特点

问题描述

在开发校验函数FUNCTION的时候,用数据跑批测试的时候报错。经排查这个校验函数FUNCTION的被一个存储过程中的update语句调用了。所以update更新数据的同时,又select了校验函数FUNCTION,猜测这两个事务冲突了导致了这个报错。

校验存储过程例如代码所示,校验存储过程P_CHECK_VALUE中的update调用了校验函数PKG_CHECK_VALUE.F_CHECK_VALUE(ARG1, ARG2):

--调用校验的存储过程
CREATE OR REPLACE PROCEDURE P_CHECK_VALUE(V_TABLENAME VARCHAR2, V_DECLAREDATE VARCHAR,V_BATCHNO VARCHAR2 DEFAULE NULL,V_4 VARCHAR2 DEFAULT NULL) IS
BEGINFOR CAL IN (...) LOOPV_SQL = 'UPDATE TABLE1 SET TABLE1.A1 = TABLE1.A1 || (SELECT TABLE2.B2 FROM TABLE2 WHERE TABLE2.NUM1 = PKG_CHECK_VALUE.F_CHECK_VALUE(ARG1, ARG2))';EXECUTE IMMDEIATE V_SQL;COMMIT;END LOOP;
END;

校验函数是写在校验包里的,例如:

--校验包的函数
CREATE OR REPLACE PACKAGE BODY "PKG_CHECK_VALUE" ISFUNCTION F_CHECK_VALUE(ARG1 VARCHAR2, ARG2 VARCHAR2) RETURN INTEGER ISBEGINSELECT COUNT(*) > 0 THEN 1 ELSE 0 ENDINTO RESULT FROM TABLE1 WHERE ...;RETURN(RESULT);END;END;
END PKG_CHECK_VALUE;

问题分析

在函数中查询某张表前对表做了更新和插入操作,使表数据发生了变化,而函数返回的数据已经发生变化,导致出错.
如果既对同一个表进行update,又调用其他触发器/函数对同一个表进行查询select操作,猜测是这两个操作同时处理一张表,导致两个事务冲突了。
不清楚会先update再select,还是先select再update,总之这两个操作是对同一张表进行了增删改查处理了。

解决办法

在函数BEGIN之前加入一个自治事务pragma autonomous_transaction;**,其中PRAGMA关键字通知PL/SQL编译器,将声明它的这个PL/SQL代码块分割为一个自治的或独立的事务。这意味着在使用 PRAGMA AUTONOMOUS_TRANSACTION 的函数或过程中,可以执行 SQL 操作并提交或回滚这些操作,而不会影响主事务中的数据。(例子中的主事务是update操作,子事务是函数的select操作)总的来说,PRAGMA AUTONOMOUS_TRANSACTION 的作用是在 PL/SQL 中创建一个独立的事务,用于执行与主事务完全独立的操作,通常用于记录日志。

PRAGMA AUTONOMOUS_TRANSACTION中文翻译过来叫“自治事务”(翻译的还算好理解),对于定义成自治事务的Procedure,实际上相当于一段独立运行的程序段,这段程序不依赖于主程序,也不干涉主程序
pragma autonomous_transaction;

修改后如下所示,不会报错了:

--校验包的函数
CREATE OR REPLACE PACKAGE BODY "PKG_CHECK_VALUE" ISFUNCTION F_CHECK_VALUE(ARG1 VARCHAR2, ARG2 VARCHAR2) RETURN INTEGER ISpragma autonomous_transaction;	--事务自治BEGINSELECT COUNT(*) > 0 THEN 1 ELSE 0 ENDINTO RESULT FROM TABLE1 WHERE ...;RETURN(RESULT);END;END;
END PKG_CHECK_VALUE;

拓展:自治事务的特点

  • 第一,这段程序不依赖于原有Main程序,比如Main程序中有未提交的数据,那么在自治事务中是查找不到的。

  • 第二,在自治事务中,commit或者rollback只会提交或回滚当前自治事务中的DML,不会影响到Main程序中的DML。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/616907.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

统计项目5000+,出具报表5分钟......捷顺科技数据中台怎么做?

捷顺创立于1992年,以智慧车行、人行出入口软硬件产品为依托,致力于智慧停车生态建设和运营,是出入口智能管理和智慧生态环境建设的开创者和引领者。 历经近三十年的发展,已经成为国内智慧停车领域的领军企业。公司集研、产、销一…

视频转码:掌握mp4视频格式转FLV视频的技巧,视频批量剪辑方法

在多媒体时代,视频格式的转换成为一种常见的需求。把MP4格式转换为FLV格式,FLV格式的视频文件通常具有较小的文件大小,同时保持了较好的视频质量。批量剪辑视频的方法能大大提高工作效率。下面来看云炫AI智剪如何进行MP4到FLV的转码&#xff…

轻量化的yolov8部署到安卓Android手机端

一、pytorch环境配置和yolov8源码安装 首先在电脑上需要配置好pytorch环境,和yolov8源码的下载 然后针对yolov8做自己的轻量化改进 二、下载Android Studio和ncnn-android-yolov8 1. Android Studio官网链接: 下载 Android Studio 和应用工具 - And…

企业数据中台整体介绍及建设方案:文件全文51页,附下载

关键词:数据中台解决方案,数据治理,数据中台技术架构,数据中台建设内容,数据中台核心价值 一、什么是数据中台? 数据中台是指通过数据技术,对海量数据进行采集、计算、存储、加工,…

面试算法119:最长连续序列

题目 输入一个无序的整数数组,请计算最长的连续数值序列的长度。例如,输入数组[10,5,9,2,4,3],则最长的连续数值序列是[2,3,4,5],因此…

2024年前端面试中JavaScript的30个高频面试题之中级知识

基础知识 高级知识 13. 什么是闭包?闭包的用例有哪些? 闭包是一个功能,它允许函数捕获定义该函数的环境(或保留对作用域中变量的访问)即使在该作用域已经关闭后。 我们可以说闭包是函数和词法环境的组合,其中定义了该函数。 换句话说,闭包为函数提供了访问自己的作用域、…

爬虫利器一览

前言 爬虫(英文:spider),可以理解为简单的机器人,如此一个“不为名利而活,只为数据而生,目标单纯,能量充沛,不怕日晒雨淋,不惧寒冬酷暑”的家伙,…

Casper Labs 与 IBM Consulting 合作,AI透明度、审计能力的新方案

​ “全新解决方案,旨在帮助企业更有效地管理训练数据,这些数据由不同的组织通过生成式人工智能系统产生” 企业区块链软件和服务提供商 Casper Labs 与 IBM Consulting 共同宣布,它们将联手推出新的解决方案,以帮助客户在其人工…

Elasticsearch初识之脚本查询附加示例代码(script)

概念 Scripting是Elasticsearch支持的一种专门用于复杂场景下支持自定义编程的强大的脚本功能,ES支持多种脚本语言,如painless,其语法类似于Java,也有注释、关键字、类型、变量、函数等,其就要相对于其他脚本高出几倍的性能&…

计算机基础(存储单位)

1. 计算机中的存储单位有哪些 1.1 常见的计算机存储单位 计算机存储单位一般用bit、B、KB、MB、GB、TB、PB、EB、ZB、YB、BB、NB、DB……来表示,如下所示: bit位、比特byte(B)字节、字Kill Byte(KB)千字…

VSCode 搭建Java开发环境

笔者使用最多的语言是C,也使用过不少其它语言,像Erlang,Python,Lua,C#等等,目前项目中在使用Go,但是没使用过Java。最近看到C#夺冠,首次荣获 TIOBE 年度编程语言,同时也看…

拯救者y9000p安装linux、windows双系统。

首先需要准备启动盘 我用的是Win32DiskImager来做的。资源使用的是ubuntu-20.04.6-desktop-amd64.iso。别用低版本,失败很多次之后的教训。 磁盘管理-磁盘分区-右键-压缩卷 这边分区出来之后,不要分配。安装时候会自动分配的。 重启之后F2进去BIOS设置…

np.polyfit

np.polyfit 是 NumPy 库中用于多项式拟合的函数。这个函数用于拟合一组数据点到一个多项式模型,返回多项式系数。 具体来说,np.polyfit(x, y, deg) 接受三个参数: x: 数据点的 x 坐标。y: 数据点的 y 坐标。deg: 多项式的阶数。 函数返回一…

Vue 中 watch监听器的使用

0. 含义: 在Vue.js中,watch是一个选项,用于监听数据的变化并执行相应的操作。watch提供了一种在数据变化时执行异步或开销较大的操作的机制,以及对一些复杂的数据变化情况做出响应。 1. 简单写法 data: {name: 静静,obj: {hobb…

DEJA_VU3D - Cesium功能集 之 114-雷达效果(基础效果)

前言 编写这个专栏主要目的是对工作之中基于Cesium实现过的功能进行整合,有自己琢磨实现的,也有参考其他大神后整理实现的,初步算了算现在有差不多实现小140个左右的功能,后续也会不断的追加,所以暂时打算一周2-3更的样子来更新本专栏(每篇博文都会奉上完整demo的源代码…

使用ArduinoMqttClient库连接阿里云,并实现发送接收数据(ESP8266)

文章目录 引言一、MQTT理论部分二、使用MQTT.fx接入物联网设备三、使用ESP8266连接阿里云四、参考例程 引言 阿里云物联网平台的接入方式有很多种,从阿里云提供的开发文档可以看到,支持的接入协议有MQTT、HTTPS、CoAP、JT/808、GB/32960协议等等&#x…

算法训练营Day40(动态规划)

今天两题都挺有难度,建议大家思考一下没思路,直接看题解,第一次做,硬想很难想出来。 343. 整数拆分 343. 整数拆分 - 力扣(LeetCode) 理解难度大,但学完其实很简单 class Solution {public …

数据库悲观锁 select for update的详解

一 作用 1.1 结论 在mysql中,select ... for update 仅适用于InnoDB,且必须在事务块中才能生效。Innodb引擎默认是行锁。 Select .... from where .... for update 如果在where的查询条件字段使用了【主键|索引】,则此命令上行锁。否…

2024,传统鞋服的“高端梦”该醒了

文 | 螳螂观察 作者 | 图霖 “一千块都不要的波司登,宝贝们还不冲吗?” 入夜,一位身着羽绒服的美女主播在灯火通明的直播间正声嘶力竭地反复呐喊。 一群不知是托还是真实消费者的用户在评论区敲出自己的身高体重,想从主播那得…

【打卡】牛客网:BM81 买卖股票的最好时机(二)

与BM80 买卖股票的最好时机(一)的区别是,可以多次买,但是卖完才能再买。 我的想法是,对于第i天的价格,j从第0天~第i-1天的价格遍历,即,【第j天买入、今天卖出的利润】【第j-1天的利润】,遍历&a…