前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >mysql事务和锁的实践

mysql事务和锁的实践

作者头像
OwenZhang
发布2021-12-08 12:23:44
3980
发布2021-12-08 12:23:44
举报
文章被收录于专栏:Owen's World

概念解释:

脏读 : 就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据

不可重复读 : 是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据,并且提交了修改。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。

幻读 : 是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。

mysql 的隔离级别

代码语言:javascript
复制
   隔离级别                      脏读      不可重复读       幻读
   未提交读(Read uncommitted)   可能      可能            可能
   已提交读(Read committed)     不可能    可能            可能
   可重复读(Repeatable read)    不可能    不可能          不可能
   可串行化(Serializable )      不可能    不可能          不可能
复制代码

实验如下:

第一次采用RC隔离级别

A窗口开启事务不提交,更新数据会锁住数据。

代码语言:javascript
复制
mysql> select * from class_teacher;
复制代码

id

class_name

teacher_id

1

aaaa

2

2

bbb

3

2 rows in set (0.00 sec)

代码语言:javascript
复制
mysql> begin;
复制代码

Query OK, 0 rows affected (0.00 sec)

代码语言:javascript
复制
mysql> update class_teacher set class_name = 'ccc' where id = 1;
复制代码

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

B窗口更新数据会因为A窗口的锁提示失败。

代码语言:javascript
复制
mysql> update class_teacher set class_name = 'ddd' where id = 1;
复制代码

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

B窗口插入数据则成功

代码语言:javascript
复制
mysql> insert into class_teacher values (3, 'eee', 4);
复制代码

Query OK, 1 row affected (0.00 sec)

RC可以避免脏读,可以避免另一个事务对已有数据进行修改。 但无法避免 可重复读:如果A窗口查询了一次数据,B窗口对该数据进行修改并且提交,A窗口再次读取数据的时候,数据已经改变。 幻读:B窗口仍能插入新数据,B窗口插入新数据后,A窗口再次读取数据,数据就会改变

第二次采用RR隔离级别

A窗口开启事务,读取数据。

代码语言:javascript
复制
mysql> begin;
复制代码

Query OK, 0 rows affected (0.00 sec)

代码语言:javascript
复制
mysql> select * from class_teacher;
复制代码

id

class_name

teacher_id

1

ddd

2

2

bbb

3

3

eee

4

4

fff

5

4 rows in set (0.00 sec)

B窗口开启事务,修改和插入数据,提交。

代码语言:javascript
复制
mysql> begin;
复制代码

Query OK, 0 rows affected (0.00 sec)

代码语言:javascript
复制
mysql> update class_teacher set class_name = 'ggg' where id = 1;
复制代码

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

代码语言:javascript
复制
mysql> insert into class_teacher values(5, 'kkk', 6);
复制代码

Query OK, 1 row affected (0.00 sec)

代码语言:javascript
复制
mysql> select * from class_teacher;
复制代码

id

class_name

teacher_id

1

ggg

2

2

bbb

3

3

eee

4

4

fff

5

5

kkk

6

5 rows in set (0.00 sec)

代码语言:javascript
复制
mysql> commit;
复制代码

A窗口再次读取数据,B窗口修改的数据不会影响到A,但新插入的数据影响到了A

代码语言:javascript
复制
mysql> select * from class_teacher;
复制代码

id

class_name

teacher_id

1

ddd

2

2

bbb

3

3

eee

4

4

fff

5

4 rows in set (0.00 sec)

RR隔离级别可以避免脏读,可重复读和幻读(注:大部分资料都写着不能解决幻读,mysql内部其实已经解决了)

GAP锁 A窗口事务未提交

代码语言:javascript
复制
mysql> update class_teacher set class_name = 'ass' where teacher_id = 2;
复制代码

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

B窗口事务

代码语言:javascript
复制
mysql> insert into class_teacher values(9,'asd',2);
复制代码

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

代码语言:javascript
复制
mysql> insert into class_teacher values(10, 'asd', 10000);
复制代码

Query OK, 1 row affected (0.00 sec)

一条成功,一条失败,mysql内部会将teacher_id=2的数据锁住

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021年11月29日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档