关于Oracle中read only Transaction

本文解析了Oracle数据库中READ ONLY事务级别的特性与限制,强调其禁止在事务中执行DML操作的特点,并通过实例展示了当使用SYS用户时,READ ONLY事务的特殊行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大家都比较知道在Oracle中可以设置事务的隔离级别,其中有一个级别是read only.

read-only
遵从事务级的读一致性,仅仅能看见在本事务开始前由其它事务提交的更改。
不允许在本事务中进行DML操作。
read only是serializable的子集。它们都避免了非重复读和幻像。
区别是在read only中是只读;而在serializable中可以进行DML操作。

看到这段解释,有的朋友就遇到问题了,主要是针对“不允许在本事务中进行DML操作”的疑惑。
(备注:先在很多同志写的资料啊,BOOK啊,都写的很含糊,不尽然,所以很容易给有些朋友
带来疑惑)

比如:
SQL> conn /as sysdba
已连接。
SQL> create table toms(no int);

表已创建。

SQL> set transaction read only;

事务处理集。

SQL> insert into toms values(1);

已创建 1 行。

SQL> commit;

提交完成。

SQL> select * from toms;

NO
----------
1

其实,Oracle在相关的doc上已经做了声明

READ ONLY
This clause is not supported for the user SYS. That is, queries by SYS will return changes
made during the transaction even if SYS has set the transaction to be READ ONLY.


所以大家今后遇到这个问题也就不必再疑惑了。再次奉劝大家,有时间还是要看官方的doc,特别是刚开始学习Oracle的同志[虽然阅读e文虽有点困难,但学习的比较系统、全面,"大侠"们写的东西,我个人认为不合适初学者,因为你这个时候还没有分辨能力,而大侠的作品又不可能写的那么全面细致,他们更多的注重的是思路、方法和一些关键步骤,可以说是眼高手疏吧。哈哈]

相关连接:Oracle中如何查询事务/会话的ISOLATION LEVEL

### SQL `WITH READ ONLY` 的用法及含义 #### 含义 `WITH READ ONLY` 是一种用于定义数据库事务或游标的选项,表示该事务或游标仅允许执行查询操作而不能修改数据。这意味着,在指定此选项的情况下,任何尝试更新、删除或插入数据的操作都会被拒绝并引发错误。 在某些数据库管理系统(DBMS),如 Oracle 中,`WITH READ ONLY` 常见于创建只读视图或定义只读事务模式时使用[^3]。而在 PostgreSQL 和其他一些支持标准 SQL 的 DBMS 中,则可能通过类似的语法实现相同的功能[^4]。 对于 MySQL 来说,“The MySQL server is running with the --read-only option” 表明整个服务器实例已被配置为全局只读状态[^1]。这并不完全等同于 SQL 标准中的 `WITH READ ONLY` 子句功能;然而两者都旨在保护特定范围内的数据免受未经授权的更改影响。 #### 使用场景 以下是几个典型的应用场合: - **防止意外的数据变更** 当希望确保某个会话期间不会发生数据变动时可以启用这种设置。 ```sql SET TRANSACTION READ ONLY; ``` - **提高性能优化查询负载高的环境** 由于不需要维护额外的日志文件来跟踪变化, 只读交易通常能带来更好的效率. - **增强安全性保障敏感信息不被篡改** #### 实际例子演示如何应用 WITH READ ONLY 下面给出一段伪代码展示了一个基于PL/SQL(Oracle)的例子: ```plsql DECLARE BEGIN OPEN my_cursor FOR SELECT * FROM employees WHERE department_id = :deptid WITH READ ONLY; END; / ``` 在这个片段里我们打开了一个带有READ ONLY属性的光标my_cursor , 它将不允许对employee表做任何形式上的DML(Data Manipulation Language)动作比如UPDATE或者DELETE语句即使这些命令是在这个光标内部合法存在的也依旧会被阻止执行.[^5] 同样地,在PostgreSQL中也可以这样声明一个只读事务: ```sql BEGIN READ ONLY; -- 执行一系列SELECT查询... COMMIT; ``` 以上脚本启动了一个新的事务块,并将其标记为只读。在此之后直到提交之前的所有工作单元都将遵循这一约束条件。试图违反它将会得到类似于这样的反馈:“ERROR: cannot run inside a read-only transaction”。 #### 注意事项 尽管利用好`WITH READ ONLY`有助于构建更加健壮稳定的应用程序架构设计思路,但也需要注意以下几点潜在风险因素: - 如果应用程序依赖频繁写入操作却误用了此类限制机制可能导致功能性障碍; - 需要确认所有涉及业务逻辑均兼容此种策略调整前后的差异表现形式;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值