MySQL居然无法保证事务的原子性?

昨晚在一场主题为 “MYSQL和PGSQL谁是世界第一” 的直播中,出现了这样一个桥段:
其中一位大佬提出MySQL一直存在一个问题或BUG,就是在 特定场景下事务无法保证原子性,并举出示例。
(如图)

实验准备

一个干净的MySQL数据库就行,我这里用的是8.0.26

实验一:

首先就是DBA最常用的黑屏界面了。
操作步骤:

1:
CREATE TABLE ttt (
id int NOT NULL,
PRIMARY KEY (id)
);
2:
insert into ttt values(1);
3:
set autocommit=0;
begin;
insert into ttt values(1);
insert into ttt values(2);
commit;
4:
select * from ttt;

(结果如图)

实验二:

相同的数据相同的操作,这次在我们常用的 运维工具Navicat 中测试
步骤相同,直接看结果

(如图)

实验三:

将两个事件的反过来

情况就是这么个情况了,那真的是MySQL的漏洞吗?

首先我们要确认几个问题:
1、谁能通过服务器直接访问我们线上数据库并操作事务,应该只有DBA才对
2、谁能通过Navicat直接操作我们线上数据库并执行事务,应该也只可能是DBA
既然是这样,那么MySQL则认为,在一个事务中有事件报错,我已经给你反馈了error(服务器端)或中止(Navicat端),那么剩下的选择权就交给你,如果你还是要commit,那么就commit执行成功的事件,如果rollback,那么就回滚整个事务

归根结底

其实就是理念问题,在上面薛老师的文章中也提到,这就是MySQL的一种设计理念,与之相对的PGSQL理念则是当一个事务中的任何事件只要出现异常则强制回滚整个事务。所以不能说这个MySQL的BUG,只能说其设计理念就是这样。
我们不妨再来个实验让大家更好理解

实验四:

1:
insert into ttt values(1);
2:
set autocommit=0;
begin;
insert into ttt values(1),(2);
commit;
3:
set autocommit=0;
begin;
insert into ttt values(2),(1);
commit;
4:
select * from ttt;

既然都说到这了,肯定有同学会想,DBA不骚整,开发骚整怎么办?
话不多说,直接上伪代码

实验五:

通过代码开启事务模拟如实验一的操作

(如图)

复盘结束

好了好了,到此结束,各位看官不必惊慌,这不能算MySQL的BUG或漏洞,也不必钻牛角尖说合不合理科不科学,只能说这种设计理念可能会让不少人产生误解。


免责声明:

1、本站资源由自动抓取工具收集整理于网络。

2、本站不承担由于内容的合法性及真实性所引起的一切争议和法律责任。

3、电子书、小说等仅供网友预览使用,书籍版权归作者或出版社所有。

4、如作者、出版社认为资源涉及侵权,请联系本站,本站将在收到通知书后尽快删除您认为侵权的作品。

5、如果您喜欢本资源,请您支持作者,购买正版内容。

6、资源失效,请下方留言,欢迎分享资源链接

文章评论

0条评论