前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MySQL数据库,详解事务处理(三)

MySQL数据库,详解事务处理(三)

作者头像
用户1289394
发布2021-11-16 11:08:30
4500
发布2021-11-16 11:08:30
举报
文章被收录于专栏:Java学习网Java学习网

REPEATABLE-READ:可重复读

将隔离级别置为REPEATABLE-READ

# 隔离级别设置,READ-UNCOMMITTED读未提交,READ-COMMITTED读已提交,REPEATABLEREAD可重复读,SERIALIZABLE串⾏

transaction-isolation=REPEATABLE-READ

重启mysql:

C:\Windows\system32>net stop mysql

mysql 服务正在停⽌..

mysql 服务已成功停⽌。

C:\Windows\system32>net start mysql

mysql 服务正在启动 .

mysql 服务已经启动成功。

查看隔离级别:

mysql> show variables like 'transaction_isolation';

+-----------------------+----------------+

| Variable_name | Value |

+-----------------------+----------------+

| transaction_isolation | REPEATABLE-READ |

+-----------------------+----------------+

1 row in set, 1 warning (0.00 sec)

先清空test1表数据:

delete from test1;

select * from test1;

按时间顺序在2个窗⼜中执⾏下⾯操作:| 1 |

+------+

2 rows in set (0.00 sec)

B窗⼜如下:

mysql> start transaction;

Query OK, 0 rows affected (0.00 sec)

mysql> insert into test1 values (1);

Query OK, 1 row affected (0.00 sec)

mysql> select * from test1;

+------+

| a |

+------+

| 1 |

| 1 |

+------+

2 rows in set (0.00 sec)

mysql> commit;

Query OK, 0 rows affected (0.00 sec)

看⼀下:

T2-A、T6-A窗⼜:⽆数据,T5-B:有数据,A看不到B的数据,说明没有脏读。

T8-A:⽆数据,此时B已经提交了,A看不到B已提交的数据,A中3次读的结果⼀样都是

没有数据的,说明可重复读。

结论:可重复读情况下,未出现脏读,未读取到其他事务已提交的数据,多次读取结果⼀

致,即可重复读。

幻读演示

幻读只会在REPEATABLE-READ(可重复读)级别下出现,需要先把隔离级别改为可重复

读。将隔离级别置为REPEATABLE-READ

# 隔离级别设置,READ-UNCOMMITTED读未提交,READ-COMMITTED读已提交,REPEATABLEREAD可重复读,SERIALIZABLE串⾏

transaction-isolation=REPEATABLE-READ

重启mysql:

C:\Windows\system32>net stop mysql

mysql 服务正在停⽌..

mysql 服务已成功停⽌。

C:\Windows\system32>net start mysql

mysql 服务正在启动 .

mysql 服务已经启动成功。

查看隔离级别:

mysql> show variables like 'transaction_isolation';

+-----------------------+----------------+

| Variable_name | Value |

+-----------------------+----------------+

| transaction_isolation | REPEATABLE-READ |

+-----------------------+----------------+

1 row in set, 1 warning (0.00 sec)

准备数据:

mysql> create table t_user(id int primary key,name varchar(16) unique

key);

Query OK, 0 rows affected (0.01 sec)

mysql> insert into t_user values (1,'路⼈甲Java'),(2,'路⼈甲Java');

ERROR 1062 (23000): Duplicate entry '路⼈甲Java' for key 'name'

mysql> select * from t_user;

Empty set (0.00 sec)

上⾯我们创建t_user表,name添加了唯⼀约束,表⽰name不能重复,否则报

错。A窗⼜如下:

mysql> start transaction;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from t_user where name='路⼈甲Java';

Empty set (0.00 sec)

mysql> insert into t_user values (2,'路⼈甲Java');

ERROR 1062 (23000): Duplicate entry '路⼈甲Java' for key 'name'

mysql> select * from t_user where name='路⼈甲Java';

Empty set (0.00 sec)

mysql> commit;

Query OK, 0 rows affected (0.00 sec)

B窗⼜如下:

mysql> start transaction;

Query OK, 0 rows affected (0.00 sec)

mysql> insert into t_user values (1,'路⼈甲Java');

Query OK, 1 row affected (0.00 sec)

mysql> select * from t_user;

+----+---------------+

| id | name |

+----+---------------+

| 1 | 路⼈甲Java |

+----+---------------+

1 row in set (0.00 sec)

T

9

c

o

m

m

it

;mysql> commit;

Query OK, 0 rows affected (0.00 sec)

看⼀下:

A想插⼊数据路⼈甲Java,插⼊之前先查询了⼀下(T5时刻)该⽤户是否存在,发现不存

在,然后在T7时刻执⾏插⼊,报错了,报数据已经存在了,因为T6时刻B已经插⼊了路⼈

甲Java。

然后A有点郁闷,刚才查的时候不存在的,然后A不相信⾃⼰的眼睛,又去查⼀次(T8时

刻),发现路⼈甲Java还是不存在的。

此时A⼼⾥想:数据明明不存在啊,为什么⽆法插⼊呢?这不是懵逼了么,A觉得如同发

⽣了幻觉⼀样。

SERIALIZABLE:串⾏

SERIALIZABLE会让并发的事务串⾏执⾏(多个事务之间读写、写读、写写会产

⽣互斥,效果就是串⾏执⾏,多个事务之间的读读不会产⽣互斥)。

读写互斥:事务A中先读取操作,事务B发起写⼊操作,事务A中的读取会导致事

务B中的写⼊处于等待状态,直到A事务完成为⽌。

表⽰我开启⼀个事务,为了保证事务中不会出现上⾯说的问题(脏读、不可重复

读、读已提交、幻读),那么我读取的时候,其他事务有修改数据的操作需要排

队等待,等待我读取完成之后,他们才可以继续。

写读、写写也是互斥的,读写互斥类似。

这个类似于java中的

java.util.concurrent.lock.ReentrantReadWriteLock类产⽣的效果。

下⾯演⽰读写互斥的效果。

将隔离级别置为SERIALIZABLE

# 隔离级别设置,READ-UNCOMMITTED读未提交,READ-COMMITTED读已提交,REPEATABLEREAD可重复读,SERIALIZABLE串⾏

transaction-isolation=SERIALIZABLE重启mysql:

C:\Windows\system32>net stop mysql

mysql 服务正在停⽌..

mysql 服务已成功停⽌。

C:\Windows\system32>net start mysql

mysql 服务正在启动 .

mysql 服务已经启动成功。

查看隔离级别:

mysql> show variables like 'transaction_isolation';

+-----------------------+--------------+

| Variable_name | Value |

+-----------------------+--------------+

| transaction_isolation | SERIALIZABLE |

+-----------------------+--------------+

1 row in set, 1 warning (0.00 sec)

先清空test1表数据:

delete from test1;

select * from test1;

按时间顺序在2个窗⼜中执⾏下⾯操作:

A

B上⾯这个演⽰的是读写互斥产⽣的效果,⼤家可以⾃⼰去写⼀下写读、写写互斥的效果。

可以看出来,事务只能串⾏执⾏了。串⾏情况下不存在脏读、不可重复读、幻读的问题

了。

关于隔离级别的选择

1. 需要对各种隔离级别产⽣的现象⾮常了解,然后选择的时候才能游刃有余

2. 隔离级别越⾼,并发性也低,⽐如最⾼级别SERIALIZABLE会让事物串⾏执⾏,并发

操作变成串⾏了,会导致系统性能直接降低。

3. 具体选择哪种需要结合具体的业务来选择。

4. 读已提交(READ-COMMITTED)通常⽤的⽐较多。

总结

1. 理解事务的4个特性:原⼦性、⼀致性、隔离性、持久性

2. 掌握事务操作常见命令的介绍

3. set autocommit可以设置是否开启⾃动提交事务

4. start transaction:开启事务

5. start transaction read only:开启只读事物

6. commit:提交事务

7. rollback:回滚事务

8. savepoint:设置保存点

9. rollback to 保存点:可以回滚到某个保存点

10. 掌握4种隔离级别及了解其特点11. 了解脏读、不可重复读、幻读

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

本文分享自 Java学习网 微信公众号,前往查看

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

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

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