测试 READ UNCOMMITTED(读取未提交)的隔离性;
insert into user values(3,'小明',1000);
insert into user values(4,'淘宝店',1000);
select * from user;
+----+-----------+-------+
| id | name | money |
+----+-----------+-------+
| 1 | a | 900 |
| 2 | b | 1100 |
| 3 | 小明 | 1000 |
| 4 | 淘宝店 | 1000 |
+----+-----------+-------+
开启一个事务操作数据
小明在淘宝店买了一个100元的零食
star transaction;
update user set money=money-100 where name='小明';
update user set money=money+100 where name='淘宝店';
淘宝店查询结果
select * from user;
SELECT * FROM user;
+----+-----------+-------+
| id | name | money |
+----+-----------+-------+
| 1 | a | 900 |
| 2 | b | 1100 |
| 3 | 小明 | 900 |
| 4 | 淘宝店 | 1100 |
+----+-----------+-------+
由于小明转账在新开启的事务上进行操作的,而该操作结果可以被其他事务(另一方淘宝店)看见,淘宝店查询结果正确,如果小明在此后rollback,我们看看会发生什么?
小明所在事务
rollback;
此时无论谁,查询会发现
+----+-----------+-------+
| id | name | money |
+----+-----------+-------+
| 1 | a | 900 |
| 2 | b | 1100 |
| 3 | 小明 | 1000 |
| 4 | 淘宝店 | 1000 |
+----+-----------+-------+
这就是所谓的脏读。一个事务读取到另一个事务还未提交的数据。
我们把隔离级别设置为read comitted;
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
SELECT @@GLOBAL.TRANSACTION_ISOLATION;
+--------------------------------+
| @@GLOBAL.TRANSACTION_ISOLATION |
+--------------------------------+
| READ-COMMITTED |
+--------------------------------+
这样再有新事务进来,它就只能查询已经提交过的事务数据了,但对于当前事务来说,它们看到的还是未提交的数据,例如:
正在操作当前事务
START TRANSACTION;
UPDATE user SET MONEY=MONEY-800 where NAME='小明';
UPDATE user SET MONEY=MONEY+800 WHERE NAME='淘宝店';
虽然隔离级别设置为READ committed ,但在当前事务中,它仍看到是数据表中临时改变的数据,而不是真正提交过的数据
SELECT * FROM user;
+----+-----------+-------+
| id | name | money |
+----+-----------+-------+
| 1 | a | 900 |
| 2 | b | 1100 |
| 3 | 小明 | 200 |
| 4 | 淘宝店 | 1800 |
+----+-----------+-------+
--假设此时在远程开启了一个新事务,连接到数据库。
$ mysql -u root -p12345612
--此时远程连接查询到的数据只能是已经提交过的
SELECT * FROM user;
+----+-----------+-------+
| id | name | money |
+----+-----------+-------+
| 1 | a | 900 |
| 2 | b | 1100 |
| 3 | 小明 | 1000 |
| 4 | 淘宝店 | 1000 |
+----+-----------+-------+
但还有这样一个问题,假设一个事务操作数据时,其他事务干扰了这个事务的数据,例如
--校长在查询数据时发现
select * from user;
+----+-----------+-------+
| id | name | money |
+----+-----------+-------+
| 1 | a | 900 |
| 2 | b | 1100 |
| 3 | 小明 | 200 |
| 4 | 淘宝店 | 1800 |
+----+-----------+-------+
--校长在求表money平均值之前,小王做了一个操作
start transaction;
insert into user values(5,'c',100);
commit;
此时表中的真实数据是:
select * from user;
+----+-----------+-------+
| id | name | money |
+----+-----------+-------+
| 1 | a | 900 |
| 2 | b | 1100 |
| 3 | 小明 | 1000 |
| 4 | 淘宝店 | 1000 |
| 5 | c | 100 |
+----+-----------+-------+
–校长在求平均值时,就不会出现不相符合的情况了
select avg(money) from user;
+------------+
| AVG(money) |
+------------+
| 820.0000 |
+------------+
虽然READ COMMITTED 让我们只能读取到其他事务已经提交的数据,但还会出现一个问题,就是在读取同一个表的数据时,可能发生前后不一致的情况,这被称为不可重复读现象(READ COMMITTED)
来源:CSDN
作者:ljm_99
链接:https://blog.csdn.net/lijiaming_99/article/details/103605415