Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >OB 运维 | OBOracle 竟然可以使用 Repeatable Read?

OB 运维 | OBOracle 竟然可以使用 Repeatable Read?

作者头像
爱可生开源社区
发布于 2024-09-14 10:54:00
发布于 2024-09-14 10:54:00
2330
举报

作者:任仲禹,爱可生数据库工程师,擅长故障分析和性能优化。

爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。

本文约 1600 字,预计阅读需要 5 分钟。


1背景

看到文章标题会有个疑惑,OceanBase 的 Oracle 模式不是只支持 2 种隔离级别:

  • 读已提交(Read Committed)
  • 可串行化(Serializable)

为什么还讨论在 OBOracle 下使用 可重复读(Repeatable Read) 隔离级别这个问题,一切的起因是交付时遇到的客户疑问:

“我的 JAVA 应用通过 oceanbase-jdbc 访问 OBOracle 数据库,业务上想实现 MySQL 可重复读的效果(即事务内 2 次相同查询看到的数据是不变的),所以我将会话设置为只读 conn.setReadOnly(true),但程序运行结果不符合业务预期。”

乍一听没完全理解,沟通后才梳理清楚:

  1. 客户了解到 set transaction read only; 命令可以实现可重复读的效果。
  2. 所以应用中配置了 conn.setReadOnly(true) 想达成此目的。

官网原文:设置 ReadOnly,不推荐执行 set session transaction readonly,推荐使用 Connection.setReadOnly(xx) 接口。

此时,问题剩俩:

  1. OBOracle 中命令 set transaction read only; 为啥能实现可重复读效果?
  2. 配置 conn.setReadOnly(true) 是否正确,不正确该如何配置?

2分析

排查涉及的环境:

  • OBOracle 模式 323bp10hotfix5
  • oceanbase-jdbc 2.4.3
为啥 set transaction read only 能实现可重复读效果?

在 OceanBase 中,只读事务中的所有查询都引用了数据库的同一份快照,从而提供多表、多查询、读取一致的视图。所以在只读事务内 2 次相同查询所看到的数据是一致的,也就实现了可重复读的效果。这在对于多用户更新相同表并且运行多个查询时的场景非常有用,也满足客户的业务需求。

配置 conn.setReadOnly 是否正确?

截取了程序运行堆栈,客户环境用的 Hikari 连接池,调用路径从下往上为【Hikari -> OceanBase-client -> setReadOnly -> setSessionReadOnly】。

最终 setSessionReadOnly 调用的是 set session transaction read only 命令。

按过往 DB 经验,“set transaction read only” 等同于 “set session transaction read only”,[session] 只是默认值而已(MySQL 就是这么做的)。*

在 OBOracle 中实验一下:

set transaction read only

时序

Session1

Session2

T1

create table a (id number);insert into a values(1);commit;select * from a; // 返回记录(1)

T2

set transaction read only;select * from a; // 返回记录(1)

T3

insert into a values(222);commit;select * from a; // 返回记录(1),(222)

T4

select * from a; // 返回记录(1)

set session transaction read only

时序

Session1

Session2

T1

create table a (id number);insert into a values(1);commit;select * from a; // 返回记录(1)

T2

set session transaction read only;select * from a; // 返回记录(1)

T3

insert into a values(222); commit;select * from a; // 返回记录(1),(222)

T4

select * from a; // 返回记录(1),(222)

通过测试可知,两者的语义和效果是不一样的。虽然都能实现其作用范围内只读,但通过和 OceanBase 支持人员了解到,还是有以下区别:

  • 作用范围不同
    • set transaction read only 仅作用于当前事务,一旦该事务结束(Commit 或 Rollback),设置失效,会话中后续事务不会继承该设置。
    • set session transaction read only 则影响整个会话中的所有事务,一旦设置,会话中接下来的所有事务都会被设置为只读模式,直到会话结束或重新设置为可读写模式。
  • 是否可以引用数据库快照
    • SET TRANSACTION 命令开启的只读事务才能引用数据库的快照(继而通过读取一致性视图以获得RR的效果)。
    • SET SEESION TRANSACTION 命令无法使只读事务获得快照。

3正确的配置方式

既然 conn.setReadOnlyset session transaction read only)无法实现效果,那如何实现 set transaction read only 命令带来的可重复读的效果呢?

OceanBase 产研提供了一个参数:要达成效果,除了需要设置 conn.setReadOnly(True) ,还需在 JDBC option 中添加参数:

  • oracleChangeReadOnlyToRepeatableRead=True

该参数在 oceanbase-client 2.4.7 引入,目的是实现可重复读(实质是快照读)的效果。

应用配置完成后,确实有效果。截止本文发布,官网查不到该参数的详细说明,我们先结合源码看下它的实现方式:

对于 setReadOnly,如果满足了 isOracleMode = trueoracleChangeReadOnlyToRepeatableRead = true 情况下,将会把会话的隔离级别设置为 setTransactionIsolation(readOnly ? 4 : 2)

本例场景下, readOnly 的值被设置是 True,那么传递给 setTransactionIsolation 方法的值就是 4 。

由上可知,当值为 4 时,JDBC 将会传递下述 SQL 给后端 OBServer:

  • SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ

前文提到 OBoracle 不是仅支持 RC 和 Serializable 吗,那该命令发到 OB上的行为是怎样的?继续测试下:

时序

Session1

Session2

T1

create table a (id number);insert into a values(1);commit;select * from a; // 返回记录(1)

T2

SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;select * from a; // 返回记录(1)

T3

insert into a values(222); commit;select * from a; // 返回记录(1),(222)

T4

select * from a; // 返回记录(1) show variables like 'transaction_isolation'\G //返回记录 VARIABLE_NAME: transaction_isolation VALUE: REPEATABLE-READ

结果是 OBOracle 可以实现可重复读的效果,且通过客户端命令查询到当前会话被设置为了 REPEATABLE READ。

4Repeatable Read 和 Serializable

最后再简单说明下,官网提到 OB 的 MySQL 模式支持 3 种隔离级别(RC、RR、Serializable),Oracle 模式支持 2 种(RC、Serializable)。但是实际在 OceanBase 数据库中只实现了 2 种隔离级别,即读已提交(RC)和可串行化(Serializable)。

  • 当用户指定 RR 隔离级别时,实际使用的是 Serializable。也就是说,OceanBase 数据库的 RR 隔离级别更加严格,不会出现幻读的异常情况。
  • 但在底层实现上,OceanBase 数据库的 Serializable 隔离级别实际使用 快照隔离(Snapshot Isolation,SI),不能保证严格的可串行化。

5结论

应用通过 oceanbase-client 驱动访问 OceanBase Oracle 模式数据库时,要想实现 Repeatable Read(可重复读) 的效果,除了需要设置 setReadOnly 为 True,还需要满足:

  • oceanbase-client >= 2.3.8 版本
  • JDBC Option 中配置 oracleChangeReadOnlyToRepeatableRead=True

OceanBase Oracle 模式数据库中,会话可以被设置为 RR 隔离级别,但会话变量只是显示为 RR ,实际底层实现上用的是快照隔离(Snapshot Isolation)。

本文关键字:#OceanBase# #Oracle# #MySQL# #事务# #隔离级别#

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-08-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 爱可生开源社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Linux——MySQL事务
当客户端A检查还有一张票时,将票卖掉,还没有执行更新数据库时,客户端B检查了票数,发现大于0,于是又卖了一次票。然后A将票数更新回数据库。这是就出现了同一张票被卖了两次。 CURD满足什么属性,能解决上述问题?
有礼貌的灰绅士
2025/05/15
510
Linux——MySQL事务
Innodb的RR到底有没有解决幻读?
在InnoDB中,Repeatable Read(重复读)隔离级别通过间隙锁和MVCC机制解决了大部分的幻读问题,但并非所有幻读都能被解决。要彻底解决幻读,需要使用Serializable(可串行化)隔离级别。
@派大星
2024/04/25
5470
Innodb的RR到底有没有解决幻读?
【Mysql-InnoDB 系列】事务模型
提到事务,大家都有基本的了解,例如mysql的事务隔离级别包括:读未提交、读已提交、可重复读、串行化;InnoDB默认是RR(可重复读);基本的MVCC等等。但大部分人对深入一些的原理就知之甚少了。本文整理事务模型的相关内容,仅供参考。
程序员架构进阶
2021/03/05
7800
MySQL事务大揭秘:事务概述和隔离级别解析
开始之前推荐一篇实用的文章:《基于生成式人工智能的三维模型自动化设计与优化》,作者:【申公豹】。
Lion 莱恩呀
2024/12/01
1820
MySQL事务大揭秘:事务概述和隔离级别解析
MySQL从删库到跑路_高级(七)——事务和锁
A、原子性(Atomicity) 表示组成一个事务的多个数据库操作是一个不可分隔的原子单元,只有所有的操作执行成功,整个事务才提交,事务中任何一个数据库操作失败,已经执行的任何操作都必须撤销,让数据库返回到初始状态。 B、一致性(Consistency) 事务操作成功后,数据库所处的状态和它的业务规则是一致的,即数据不会被破坏。 C、隔离性(Isolation) 在并发数据操作时,不同的事务拥有各自数据空间,它们的操作不会对对方产生干扰。数据库规定了多种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高,数据一致性越好,但并发性越弱。 D、持久性(Durabiliy) 一旦事务提交成功后,事务中所有的数据操作都必须被持久化到数据库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须能保证能够通过某种机制恢复数据。
良月柒
2019/03/19
7510
Mysql为何使用可重复读(Repeatable read)为默认隔离级别?
群里有小伙伴面试时,碰到面试官提了个很刁钻的问题:Mysql为何使用可重复读(Repeatable read)为默认隔离级别??? 下面进入正题: 我们都知道事务的几种性质 :原子性、一致性、隔离性和
Java宝典
2021/07/15
1.9K0
深入理解InnoDB的MVCC多版本并发机制
上面我们说到了InnoDB在RR隔离级别下解决了幻读问题,又保证了高并发的读取(避免了读写串行化),那他到底是如何做的呢?
绿水长流z
2025/01/03
1270
深入理解InnoDB的MVCC多版本并发机制
JAVA保姆式上手教程之入门精通案例
<img src="assets/image-20211123160059187.png" alt="image-20211123160059187" style="zoom: 33%;" />
张哥编程
2024/12/13
980
【眼见为实】自己动手实践理解数据库REPEATABLE READ && Next-Key Lock
[REPEATABLE READ]隔离级别解决了不可重复读的问题,一个事务中多次读取不会出现不同的结果,保证了可重复读。 还是上一篇中模拟不可重复读的例子: 事务1:
撸码那些事
2018/06/16
6240
行锁:InnoDB 替代 MyISAM 的重要原因
MySQL 5.5 之前的默认存储引擎是 MyISAM,5.5 之后改成了 InnoDB。InnoDB 后来居上最主要的原因就是:
jeanron100
2019/11/24
8800
转账会不会出现钱扣了对方也没收到钱的情况?
今天大年初五迎财神,那么提到“财”,我们是否考虑过一个问题:转账会不会出现钱扣了对方也没收到钱的情况?首先财神不同意,另外按照现在的技术,基本也不会出现,因为目前一个转账操作基本在一个事务中。事务内的语句,要么全部执行成功,要么全部执行失败。也就是说,上面转账过程中,即使中间出现问题,也会回滚,取消扣钱操作。
数据库交流
2022/04/25
3650
InnoDB中的事务隔离级别与锁
一个事务在进行数据变更时对另一个事务产生的可见性影响描述,表达为 脏读、幻读、不可重复读三个概念。下面具体解释下对应概念。
知一
2021/12/07
7180
InnoDB中的事务隔离级别与锁
干了三年Java后端,你竟然还不知道MySQL的四大隔离级别?
之前分析一个死锁问题,发现自己对数据库隔离级别理解还不够清楚,所以趁着这几天假期,整理一下MySQL事务的四大隔离级别相关知识,希望对大家有帮助~
Java程序猿
2021/02/20
5260
Mysql之锁与事务
平时的业务中,顶多也就是写写简单的sql,连事务都用的少,对锁这一块的了解就更加欠缺了,之前一个大神分享了下mysql的事务隔离级别,感觉挺有意思的,正好发现一个很棒的博文,然后也收集了一些相关知识,正好来学习下,mysql中锁与事务的神秘面纱,主要内容包括
一灰灰blog
2018/03/26
1.3K0
Mysql之锁与事务
深入理解 MySQL ——锁、事务与并发控制
每个连接都会在 MySQL 服务端产生一个线程(内部通过线程池管理线程),比如一个 select 语句进入,MySQL 首先会在查询缓存中查找是否缓存了这个 select 的结果集,如果没有则继续执行解析、优化、执行的过程;否则会之间从缓存中获取结果集。
杨振涛
2019/04/19
7620
深入理解 MySQL ——锁、事务与并发控制
MySQL 学习笔记(二)MVCC 机制
之前在讲 MySQL 事务隔离性提到过,对于写操作给读操作的影响这种情形下发生的脏读、不可重复读、虚读问题。是通过MVCC 机制来进行解决的,那么MVCC到底是如何实现的,其内部原理是怎样的呢?我们要抓住三个方面:记录中的4个隐藏字段、undo log 和 read view。
归思君
2023/10/16
2750
MySQL 学习笔记(二)MVCC 机制
mysql-选择使用Repeatable read的原因
在mysql调优的过程中发现,mysql的默认隔离级别是可重复读(repeatable read),其他几类关系型数据库pg,以及sybase,oracle,sqlserver的默认的隔离级别都是读已提交(read committed)。
用户7353950
2022/06/23
7030
关于数据库事务的知识点归纳
在MySQL数据库管理系统中,默认情况下,事务是自动提交的,也就是说,只要执行一条DML语句,开启了事务,并且提交了事务。
wuweixiang
2019/03/12
7030
网易三面:说说你对MySQL事务四大隔离的理解
之前分析一个死锁问题,发现自己对数据库隔离级别理解还不够清楚,所以趁着这几天假期,整理一下MySQL事务的四大隔离级别相关知识,希望对大家有帮助,MySQL笔记需要可以自取。
Java程序猿
2022/04/03
2740
Mysql RC/RR隔离原理和区别 不可重复读和可重复读
mysql四种隔离级别: 1.未提交读(READ UNCOMMITED)脏读 2.已提交读 (READ COMMITED)简称(RC) 不可重复读 3.可重复读(REPEATABLE READ)简称(RR) 4.可串行化(SERIALIZABLE) 这个不用验证了,所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰了,一般不用,性能特别低。
oktokeep
2024/10/09
3100
Mysql RC/RR隔离原理和区别 不可重复读和可重复读
推荐阅读
相关推荐
Linux——MySQL事务
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档