讲师中心 微信公众号
AI工具推荐 视频效率加速

Oracle 19c中如何编写高可用环境下的只读事务存储过程?

阿伟酱_2495

阿伟酱_2495

发布时间:2026-11-04 11:29:00

|

583人浏览过

|

来源于php中文网

原创

是,必须显式声明只读。Oracle 19c ADG备库要求存储过程通过READS SQL DATA等PRAGMA明确标识只读性,否则即使仅含SELECT也会因无法静态确认只读性而报ORA-16000;自治事务、隐式写操作(如DBMS_APPLICATION_INFO)及未授权对象访问均被禁止。

oracle 19c中如何编写高可用环境下的只读事务存储过程?

只读事务在 ADG 备库上执行失败,是不是没加 READ ONLY 修饰?

不是所有“只读”操作都会被备库接受。Oracle 19c 在 Active Data Guard(ADG)环境下,SELECT 语句默认可在备库执行,但存储过程若隐含写行为(比如调用 DBMS_OUTPUT.PUT_LINE、访问未授权视图、或内部触发自治事务),仍可能报错 ORA-16000: database open for read-only access。关键不是“看起来只读”,而是 Oracle 是否能静态确认其只读性。

必须显式声明存储过程为只读,否则即使内容全是 SELECT,也可能被拒绝执行。这是最常被忽略的一步。

  • 使用 READS SQL DATA 显式声明:仅读取数据,不修改
  • 避免任何可能触发 DML 的逻辑,包括 INSERT INTO ... SELECT、CREATE GLOBAL TEMPORARY TABLE(即使临时表也不行)、DBMS_SCHEDULER.CREATE_JOB 等
  • 不要在过程中调用未标记只读的自定义函数——它们会污染整个调用链
  • 验证方式:SELECT OBJECT_NAME, STATUS, AUTHID FROM USER_PROCEDURES WHERE PROCEDURE_NAME = 'YOUR_PROC';,确认状态为 VALID 且无隐式权限升级

为什么在备库执行 PRAGMA AUTONOMOUS_TRANSACTION 会直接报错?

自治事务本质上是“嵌套的独立事务”,它需要自己的事务控制(COMMIT/ROLLBACK),而物理备库处于 READ ONLY WITH APPLY 模式,禁止任何本地事务提交。哪怕你只是想往一张日志表里插一条记录,PRAGMA AUTONOMOUS_TRANSACTION 也会让 Oracle 认为该过程具备写能力,从而拒绝加载或执行。

QuantOracle
QuantOracle

63个确定性量化金融计算器 + 10个通过MCP的复合工作流。期权定价、Greeks、奇异衍生品、风险指标、投资组合优化……

下载
  • ADG 备库不允许任何本地事务生命周期管理,AUTONOMOUS_TRANSACTION 是硬性禁用项
  • 替代方案:改用主库专用连接(如通过 DBMS_SCHEDULER 或应用层路由),或把日志写入外部系统(如 UTL_HTTP 发送到日志服务)
  • 注意 DBMS_APPLICATION_INFO.SET_MODULE 这类“看似只读”的过程,实际会更新 V$SESSION,也属于隐式写操作,同样不可用

ADG_REDIRECT_DML = TRUE 开了,但存储过程里的 DML 还是报错,问题出在哪?

DML 重定向只对**直接执行的 DML 语句**生效,不自动穿透到存储过程内部。也就是说,你在备库 EXEC my_proc,即使过程体里有 UPDATE,也不会被重定向——Oracle 会直接拒绝编译或运行该过程,因为过程定义本身已违反只读约束。

  • 过程必须在主库创建并编译(通过 Redo 同步到备库),且不能包含任何 DML 语句
  • 如果真需要“备库可写”,只能把 DML 拆出来,由应用层在备库显式发起(如 INSERT /*+ ADG_REDIRECT */ INTO ...),再由过程处理返回结果
  • 参数 ADG_REDIRECT_DML 对 PL/SQL 块中的 DML 无效,只作用于顶层 SQL 语句
  • 检查是否误用了 FOR UPDATE:即使没 UPDATE,带 FOR UPDATE 的游标在备库也会报 ORA-16000

如何确保只读存储过程在主备切换后仍可用?

主备角色切换后,原备库变为主库,原主库变为备库。如果你的过程依赖特定数据库角色(比如查 V$DATABASE.DATABASE_ROLE 判断当前是主还是备),就可能出错——因为过程代码没变,但执行环境变了。

  • 避免在过程中硬编码角色判断逻辑;如需差异化行为,应由应用传入上下文参数
  • 所有对象(表、视图、同义词)必须在主备库中完全一致,包括权限和统计信息;否则备库执行时可能因对象不存在或权限不足而失败
  • 特别注意 SYSDATE 和 SYSTIMESTAMP:它们在主备库上值不同,若过程逻辑依赖时间差(如“过去5分钟的数据”),切换后行为会漂移
  • 测试必须覆盖 Switchover 场景:手动执行一次 ALTER DATABASE COMMIT TO SWITCHOVER TO STANDBY,再验证过程是否仍可执行
真正的难点不在语法,而在对“只读”的理解是否穿透到了执行路径每一层——从过程定义、所调用的每个函数、到隐式使用的系统包,只要有一处越界,整个过程在 ADG 备库上就会失效。

热门AI工具

更多
Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

小橡皮AI

一款AI工具,主要用于小橡皮一键去AI味,将机器味重的内容改得更有活人感,防止因为 AI 内容被平台打上 AI 标签,以及限流,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

4743

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

971

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

1249

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

6741

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

3463

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

6740

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

9301

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

1270

2024.04.29

Docker Desktop怎么设置端口映射
Docker Desktop怎么设置端口映射

本专题聚焦Docker Desktop容器端口映射与访问配置,整理从创建容器、设置端口绑定到验证本地服务访问的操作流程。针对端口被占用、映射配置错误、容器服务无法访问等情况,也提供相应的检查方向,方便用户完成端口配置。

0

2026.11.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn