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

本文涉及的产品
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
简介: 在交付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数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
1月前
|
Oracle 安全 关系型数据库
Oracle与GreatSQL差异:更改唯一索引列
【11月更文挑战第1天】本文介绍了在 Oracle 和 GreatSQL 中更改唯一索引列的方法及差异。Oracle 需要手动删除和重建索引,过程复杂且可能影响数据一致性;而 GreatSQL 可以自动维护索引,直接修改列值即可,操作简便且更安全。
|
1月前
|
SQL Oracle 关系型数据库
Oracle与GreatSQL差异:更改唯一索引列
【11月更文挑战第11天】本文介绍了在 Oracle 和 GreatSQL 中修改唯一索引列的操作。Oracle 需要先删除索引、修改列值,再重新创建索引,步骤较为繁琐。而 GreatSQL 在满足一定条件下支持在线 DDL 操作,可以直接修改列值,操作相对简单。两者都需要考虑数据完整性和表上的其他约束条件。
|
3月前
|
存储 Oracle 关系型数据库
Oracle和MySQL有哪些区别?从基本特性、技术选型、字段类型、事务、语句等角度详细对比Oracle和MySQL
从基本特性、技术选型、字段类型、事务提交方式、SQL语句、分页方法等方面对比Oracle和MySQL的区别。
692 18
Oracle和MySQL有哪些区别?从基本特性、技术选型、字段类型、事务、语句等角度详细对比Oracle和MySQL
|
5月前
|
Oracle 安全 关系型数据库
|
5月前
|
存储 Oracle 关系型数据库
|
5月前
|
Oracle 关系型数据库 数据库
|
5月前
|
存储 Oracle 关系型数据库
关系型数据库Oracle运行RMAN脚本
【7月更文挑战第23天】
56 4
|
5月前
|
SQL Oracle 关系型数据库
关系型数据库Oracle设置 RMAN 环境:
【7月更文挑战第25天】
79 2
|
5月前
|
监控 Oracle 算法
|
5月前
|
SQL Oracle 关系型数据库
关系型数据库Oracle结束 RMAN 会话:
【7月更文挑战第25天】
112 1

推荐镜像

更多