一.概要
总结:REPEATABLE READ是在READ COMMITTED的基础上,限制事务自身不受到外部影响(不管途中其他事务是否commit更改操作),对数据的查询结果始终与本身事务的操作结果一致。
二.实验记录
示例环境:docker中的mysql 容器
以book表为共享资源,打开一个session对其进行写操作,打开一个session对其进行读操作。
mysql事务隔离级别默认为REPEATABLE READ.
那么我们先来看RC(READ COMMITTED)级别的事务。
此时你需要更改会话的事务隔离级别为RC级别,设置和校对命令如下:
mysql> set session transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)
mysql> select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| READ-COMMITTED |
+----------------+
1.RC(READ COMMITTED)级别
(1).新建事务1,查询book表:
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from book;
+---------+------------------+--------+
| book_id | name | number |
+---------+------------------+--------+
| 1000 | Java程序设计 | 10 |
| 1001 | 数据结构 | 10 |
| 1002 | 设计模式 | 10 |
| 1003 | 编译原理 | 10 |
| 1004 | 开发者 | 11 |
| 1005 | developer | 11 |
| 1006 | developer 3 | 11 |
+---------+------------------+--------+
(2).新建事务2,对book_id=1006的数据进行修改,未提交:
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> update book set name ='developer 1' where book_id=1006;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
(3).在事务1中再次查询,发现结果未变动。
mysql> select * from book;
+---------+------------------+--------+
| book_id | name | number |
+---------+------------------+--------+
| 1000 | Java程序设计 | 10 |
| 1001 | 数据结构 | 10 |
| 1002 | 设计模式 | 10 |
| 1003 | 编译原理 | 10 |
| 1004 | 开发者 | 11 |
| 1005 | developer | 11 |
| 1006 | developer 3 | 11 |
+---------+------------------+--------+
(4).在事务2上提交执行:
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
此时在事务1上再次查询,查到的结果有变动。
mysql> select * from book;
+---------+------------------+--------+
| book_id | name | number |
+---------+------------------+--------+
| 1000 | Java程序设计 | 10 |
| 1001 | 数据结构 | 10 |
| 1002 | 设计模式 | 10 |
| 1003 | 编译原理 | 10 |
| 1004 | 开发者 | 11 |
| 1005 | developer | 11 |
| 1006 | developer 1 | 11 |
+---------+------------------+--------+
7 rows in set (0.00 sec)
2.RR(REPEATABLE READ)级别
(1).新建事务1,查询book表,未提交。
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from book;
+---------+------------------+--------+
| book_id | name | number |
+---------+------------------+--------+
| 1000 | Java程序设计 | 10 |
| 1001 | 数据结构 | 10 |
| 1002 | 设计模式 | 10 |
| 1003 | 编译原理 | 10 |
| 1004 | 开发者 | 11 |
| 1005 | developer | 11 |
| 1006 | developer 1 | 11 |
+---------+------------------+--------+
7 rows in set (0.00 sec)
(2).新建事务2,对book_id=1006的数据进行修改,并提交。
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> update book set name ='开发者 1' where book_id=1006;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
(3).回到事务1,再次查询,不提交。查到的结果未改变。
mysql> select * from book;
+---------+------------------+--------+
| book_id | name | number |
+---------+------------------+--------+
| 1000 | Java程序设计 | 10 |
| 1001 | 数据结构 | 10 |
| 1002 | 设计模式 | 10 |
| 1003 | 编译原理 | 10 |
| 1004 | 开发者 | 11 |
| 1005 | developer | 11 |
| 1006 | developer 1 | 11 |
+---------+------------------+--------+
7 rows in set (0.00 sec)
(4).当事务1提交后再查询,得到的结果才是新的。
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from book;
+---------+------------------+--------+
| book_id | name | number |
+---------+------------------+--------+
| 1000 | Java程序设计 | 10 |
| 1001 | 数据结构 | 10 |
| 1002 | 设计模式 | 10 |
| 1003 | 编译原理 | 10 |
| 1004 | 开发者 | 11 |
| 1005 | developer | 11 |
| 1006 | 开发者 1 | 11 |
+---------+------------------+--------+
7 rows in set (0.00 sec)