我的编程空间,编程开发者的网络收藏夹
学习永远不晚

mysql环境RR隔离级别如何转换成RC

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

mysql环境RR隔离级别如何转换成RC

下文我给大家简单讲讲关于mysql环境RR隔离级别如何转换成RC,大家之前了解过相关类似主题内容吗?感兴趣的话就一起来看看这篇文章吧,相信看完mysql环境RR隔离级别如何转换成RC对大家多少有点帮助吧。

先了解RR(REPEATABLE-READ)和RC(READ-COMMITTED)的区别.

RR隔离级别增加了间隙锁,避免了幻读,并且阻止了不可重复读,让同一个事务里面的查询和修改都是一致的.mysql默认的隔离级别就是RR.

虽然说RC隔离级别在同一个事务内会存在查询出不同数据的现象,但是这些数据都必然是提交过的,是真实存进硬盘的数据.所以也不用过分担忧,而且RC隔离级别反而降低了锁粒度,也不是毫无用处.oracle和sql server默认的隔离级别类似RC.

所以说也不是说RC就绝对不好,要看场景来选择,而这里只是简介,不打算深入.

操作流程说明:因系统高并发下,存在多个会话可能同时更新同一条记录的问题,但是值是一样的.问题就在于事务里面存在RR隔离级别转换成RC的问题,造成数据返回不正确,导致代码返回错误,但是数据是准确的.


正常的RR事务

先看当前环境信息:

#当前的mysql版本
mysql> select @@version;
+------------+
| @@version  |
+------------+
| 5.6.39-log |
+------------+
1 row in set (0.00 sec)
#当前的隔离级别
mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set (0.00 sec)
#当前的binlog格式
mysql> show variables like 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | MIXED |
+---------------+-------+
1 row in set (0.00 sec)

先看一个正常的事务:

#开启事务

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

#开启事务

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

#当前记录是一致的

mysql> select express_cost from m_order_sub where order_sub_no = 'O152022324482662671828';

+--------------+
| express_cost |
+--------------+
|         2000 |
+--------------+
1 row in set (0.02 sec)

#当前记录是一致的

mysql> select express_cost from m_order_sub where order_sub_no = 'O152022324482662671828';

+--------------+
| express_cost |
+--------------+
|         2000 |
+--------------+
1 row in set (0.02 sec)

#这边先更新一条记录

mysql> update m_order_sub set express_cost = 3000 where order_sub_no = 'O152022324482662671828';

Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0


#这边后更新一条记录,但是另一边并没有commit,所以这边处于等待释放锁

update m_order_sub set express_cost = 3000 where order_sub_no = 'O152022324482662671828';

#这边再查询一次,记录成功修改

mysql> select express_cost from m_order_sub where order_sub_no = 'O152022324482662671828';

+--------------+
| express_cost |
+--------------+
|         3000 |
+--------------+
1 row in set (0.00 sec)

#提交事务

mysql> commit;

Query OK, 0 rows affected (0.01 sec)

#然后锁释放后这边的更新也执行完了,但是因为更新的值是一样的,所以并没有修改到记录,Changed为0

Query OK, 0 rows affected (12.40 sec)

Rows matched: 1  Changed: 0  Warnings: 0

#这边再查询一次,记录成功修改,是最新数据

mysql> select express_cost from m_order_sub where order_sub_no = 'O152022324482662671828';

+--------------+
| express_cost |
+--------------+
|         3000 |
+--------------+
1 row in set (0.00 sec)

#这边查询结果是旧的,因为记录并没有被修改到,所以显示的也是事务开始时的数据

mysql> select express_cost from m_order_sub where order_sub_no = 'O152022324482662671828';

+--------------+
| express_cost |
+--------------+
|         2000 |
+--------------+
1 row in set (0.00 sec)

#提交并退出事务

mysql> commit;

Query OK, 0 rows affected (0.13 sec)

#这时就显示最新的数据了

mysql> select express_cost from m_order_sub where order_sub_no = 'O152022324482662671828';

+--------------+
| express_cost |
+--------------+
|         3000 |
+--------------+
1 row in set (0.00 sec)

这是一个正常的情况,因为记录并没有被修改到,所以显示的也是事务开始时的数据,保证了RR级别的可重复读特性.


问题现象

下面来看另一个不正常的情况,环境是和上面一致的,没有改变,我们来直接看图:

mysql环境RR隔离级别如何转换成RC

可以看到,执行方式和上面一致,右边的事务等待了12秒后执行了,也就是左边commit之后.但是,变成了不可重复读,右边事务里面没有commit也可以看到最新提交的数据,甚是诡异.


解决方法

第一种方案:将隔离级别改成RC貌似是可以解决问题,但是解决的是左边的问题,把可重复读的特性改成了不可重复读了而已.这样两边都能查到已经提交的新数据.

#更改mysql全局隔离级别为RC
set global tx_isolation = 'READ-COMMITTED'

改了之后,全局都变成了不可重复读,并且没有了间隙锁,也正因为可以看到已经提交的新数据,所以上面正常的情况也会跟下面一致,但是不代表有问题,这本身就是RC隔离级别的特点.

然后有人说,这不是没解决问题嘛,只是把问题全部改成一样而已,好像是这样.所以就有第二种方案.


第二种方案:把binlog格式改成ROW,不用改隔离级别,问题是真的解决了.

#把全局binlog格式改成ROW格式
set global binlog_format = 'ROW';

在上面看到原始的的binlog格式是MIXED混合模式,现在改成ROW模式,再试一遍.

mysql环境RR隔离级别如何转换成RC

好了,一切正常了,这就是RR的特性,可重复读.

大家觉得mysql环境RR隔离级别如何转换成RC这篇文章怎么样,是否有所收获。如果想要了解更多相关,可以继续关注我们的行业资讯板块。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

mysql环境RR隔离级别如何转换成RC

下载Word文档到电脑,方便收藏和打印~

下载Word文档

编程热搜

目录