本文共 3943 字,大约阅读时间需要 13 分钟。
show global variables like ‘tx_isolation ';| tx_isolation | READ-COMMITTED |
session 1 | session 2 |
begin |
|
| begin |
select * from v where id=1; | id | name | | 1 | name11 | |
|
| select * from v where id=1; | id | name | | 1 | name11 | |
select * from v where id=1 lock in share mode; | id | name | | 1 | name11 | |
|
| select * from v where id=1 lock in share mode; | id | name | | 1 | name11 |
session1 和 sesssion2 请求的都是共享锁,不会互斥,因此无需等待。 |
select * from v where id=1 for update; | id | name | | 1 | name11 |
这个时候,由于 session2 发起了 lock in share mode ,需要请求一个共享锁,和 for update 所需要的排它锁是互斥的,因此 session1 需要等待 session2 提交或回滚才能继续。 |
|
| commit;
select * from v where id=1; | id | name | | 1 | name11 | |
| select * from v where id =1 for update; 或者 select * from v where id =1 lock in share mode; |
update v set name = 'name 2' where id=1; | session1 首先发起了一个 select ..for update 请求,会对该记录加一个排它锁,因此 session2 的请求会被等待,直到 session1 提交或者回滚。 |
commit; | |
| | id | name | | 1 | name 2 | |
select * from v where id =1; | id | name | | 1 | name 2 | |
|
| select * from v where id =1; | id | name | | 1 | name11 | |
| select * from v where id =1 lock in share mode; | id | name | | 1 | name 2 |
可以看到,如果只是发起最简单的 select 请求,则返回的结果是 session2 发生时看到的快照;如果发起一个 select…for update 或 select..lock in share mode ,则可以看到最新的快照。 这是因为 select…for update 或 select…lock share mode 会取得最新快照,并且请求加一个排它或者共享 next-key 锁。而普通的 select 查询不会请求加任何锁。 |
| update v set name = ‘name 1’ where id =1; commit; |
select * from v where id=1; | id | name | | 1 | name 1 |
可以看到 session2 提交后的最新结果。 |
|
| select * from v where id=1; | id | name | | 1 | name 1 |
可以看到 session2 提交后的最新结果。 |
show global variables like ‘tx_isolation ';| tx_isolation | REPEATABLE-READ |
session 1 | session 2 |
begin; |
|
| begin; |
select * from v where id=1 lock in share mode; | id | name | | 1 | name 1 | |
|
| select * from v where id=1 lock in share mode; | id | name | | 1 | name 1 |
session1 和 sesssion2 请求的都是共享锁,不会互斥,因此无需等待。 |
select * from v where id=1 for update; | id | name | | 1 | name 1 |
这个时候,由于 session2 发起了 lock in share mode ,需要请求一个共享锁,和 for update 所需要的排它锁是互斥的,因此 session1 需要等待 session2 提交或回滚才能继续。 |
|
| commit; |
| begin;
select * from v where id=1; | id | name | | 1 | name 1 | |
update v set name='name 2' where id=1; |
|
| select * from v where id=1 for update; 或 select * from v where id =1 lock in share mode; |
| session1 首先发起了一个 select ..for update 请求,会对该记录加一个排它锁,因此 session2 的请求会被等待,直到 session1 提交或者回滚。 |
commit; |
|
| | id | name | | 1 | name 2 | |
select * from v where id=1; | id | name | | 1 | name 2 | |
|
| select * from v where id=1 lock in share mode; | id | name | | 1 | name 2 | |
| select * from v where id=1; | id | name | | 1 | name 2 |
这个时候,不管是 select…lock in share mode 还是 select…for update ,得到的结果都是 session 1 更新后提交的数据。 |
| update v set name = 'name 1' where id=1; |
select * from v where id=1; | id | name | | 1 | name 2 | |
|
| commit; |
| select * from v where id=1 ; | id | name | | 1 | name 1 | |
select * from v where id=1 ; | id | name | | 1 | name 1 | |
|