Oracle只读事务和PolarDB只读事务的差异

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
简介: 在交付PolarDB的过程中我们也遇到了只读事务造成的困扰,本文主要介绍Oracle只读事务和PolarDB只读事务的不同。

在交付PolarDB的过程中我们也遇到了只读事务造成的困扰,本文主要介绍Oracle只读事务和PolarDB只读事务的不同。

前言

Oracle提供了只读事务,同样的PolarDB也提供了只读事务,虽然名称一样,但是此非彼,两个概念存在差异。在交付PolarDB的过程中我们也遇到了只读事务造成的困扰,本文主要介绍Oracle只读事务和PolarDB只读事务的不同。

我们遇到的案例

客户从Oracle迁移到PolarDB Oracle,在进行功能测试过程中,手动开启事务执行DML操作,会报:can not execute update in a read-only transaction,而客户的应用在Oracle上运行正常,由此引发了后续的排查和定位。

Oracle只读事务

Oracle默认情况下保证了SQL语句级别的读一致性,即在一条SQL语句执行期间,它只会看到执行前点的数据状态,而不会看到执行期间数据被其他SQL改变的状态。如果你在一个事务里执行多次查询,想确保每次查询的数据都一致,也就是类似repeatable-read(可重复度),Oracle的只读查询则保证了事务级别的读一致性,即在该事务范围内执行的多条SQL都只会看到执行前点的数据状态,而不会看到事务期间的任何被其他 SQL改变的状态。除开查询一致性的特性,只读事务功能和PolarDB一致。

如何开启只读事务

#jdbc 该方式不生效
connection.setReadOnly(true);

#jdbc 生效
statement.execute("set transaction read only ");

我们先来看看JDBC 的协议说明:

    /**
     * Puts this connection in read-only mode as a hint to the driver to enable
     * database optimizations.
     *
     * <P><B>Note:</B> This method cannot be called during a transaction.
     *
     * @param readOnly <code>true</code> enables read-only mode;
     *        <code>false</code> disables it
     * @exception SQLException if a database access error occurs, this
     *  method is called on a closed connection or this
     *            method is called during a transaction
     */
    void setReadOnly(boolean readOnly) throws SQLException;

在实际项目中我们遇到了客户开启只读事务的场景,客户通过setReadOnly的方式开启,但是实际上并没有生效,查看代码,Oracle jdbc驱动设置只读,只是对readOnly参数赋值,并没有执行:set transaction read only。

image.png

查看Oracle 官方文档:Read-only connections are supported by the Oracle server, but not by the Oracle JDBC drivers.。和我们的测试结果吻合,必须执行set transaction read only 才能开启只读事务,而客户侧是通过setReadOnly来开启只读事务,基本能确定客户的配置没有生效。下图是客户的事务配置:

image.png

PolarDB只读事务

PolarDB的只读事务和Oracle类似,开启了只读事务后,都不能执行DML,但是PolarDB不保证事务里可重复度的隔离级别。

在这个case里,为什么同样的配置到PolarDB表现不一样?为什么切换到PolarDB只读事务生效了?我们继续进行debug,在PolarDB上执行setReadOnly(true),可以看到jdbc驱动向server端发送了set session characteristics as transaction read only 的操作,和Oracle的实现完全不同。如图:

image.png

总结

通过测试我们能看到在JDBC层面Oracle和PolarDB对只读事务的开启方式是有差异的,实际上客户侧在Oracle的只读事务配置并没有生效,更换到PolarDB后,因为jdbc实现差异,开启了只读事务,所以导致客户在功能测试阶段大量出现只读事务的异常。如果客户侧真正开启了只读事务,PolarDB怎么去保证和Oracle只读事务一致性读特性一致,临时设置当前事务的隔离级别为repeatable-read是一个相对成本低的改造方案。

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
存储 设计模式 Oracle
Oracle跨数据库实现定时同步指定表中的数据
Oracle跨数据库实现定时同步指定表中的数据
|
12天前
|
关系型数据库 MySQL Go
数据库的事务操作
数据库的事务操作
|
23天前
|
SQL 存储 Oracle
Oracle语句级触发器:数据库的“隐形哨兵”
【4月更文挑战第19天】Oracle语句级触发器是数据库中的自动执行程序,当特定事件(如INSERT、UPDATE、DELETE)发生时,会针对整个SQL语句触发。以新员工入职记录日志为例,创建语句级触发器可自动在操作后向日志表插入信息,减少手动工作并提高性能。虽然无法处理行级详细信息,但在处理大量数据时,相比行级触发器更高效。掌握触发器使用能提升数据管理效率和安全性。
|
SQL 存储 运维
Oracle数据库 | Oracle并发与一致性
Oracle数据库 | Oracle并发与一致性
249 0
Oracle数据库 | Oracle并发与一致性
|
存储 Oracle 关系型数据库
Oracle 10g通过创建物化视图实现不同数据库间表级别的数据同步
Oracle 10g通过创建物化视图实现不同数据库间表级别的数据同步
LXJ
|
关系型数据库 数据库 数据安全/隐私保护
PostgreSQL创建只读用户
PostgreSQL创建只读用户
LXJ
273 0
|
关系型数据库 数据库 RDS
PolarDB-X 1.0-常见问题-事务问题-在PolarDB-X上执行事务操作的时候提示不支持跨库事务,该如何解决?
在PolarDB-X上,可以将事务简单分类为如下两种: 单机事务:所有的事务操作都落在同一个RDS数据库。
254 0
|
关系型数据库 PostgreSQL
PostgreSQL 怎样创建“只读用户”?
PostgreSQL其实没有只读用户的语法,那么PostgreSQL提供了用户/角色属性来达到只读用户的效果,步骤如下: 1. 创建一个用户名为<readonlyuser>,密码为<your_own_password>的用户 CREATE USER <readonlyuser> ...
5938 0
|
Oracle 关系型数据库 数据库

推荐镜像

更多