设为首页 加入收藏

TOP

MySQL温故而知新--Innodb存储引擎中的锁(四)
2014-11-24 03:18:45 来源: 作者: 【 】 浏览:12
Tags:MySQL 温故而知新 --Innodb 存储 引擎
t (0.01 sec)

mysql>

但是如果在REPEATABLE-READ事务隔离级别下,总是读取事务开始时的数据,所以得到的结果截然不同,如下所示:

mysql> show variables like 'tx_isolation';

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

| Variable_name | Value |

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

| tx_isolation | REPEATABLE-READ |

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

1 row in set (0.00 sec)

mysql> select * from t1 where a=1;

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

| a | b | c |

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

| 1 | c0 | c2 |

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

1 row in set (0.00 sec)

mysql> select * from t1 where a=111;

Empty set (0.00 sec)

mysql>

对于READ-COMMITTED的事务隔离级别而言,从数据库理论的角度来看,其实违反了事务ACID的I的特性,既是隔离性,整理成时序表,如下图所示。

Time

Session A

Session B

| time 1

Begin;

Select * from t1 where a=1;有记录

| time 2

Begin;

Update t1 set a=111 where a=1;

| time 3

Select * from t1 where a=1;有记录

| time 4

Commit;

| time 5

Select * from t1 where a=1; 无记录

V time 6

Commit;

如果按照ACID原理中的I原理隔离性,在整个会话中Session A中,Select * from t1 where a=1;应该查询出来的数据保持一直,但是在time 5那一刻 Session A未结束的时候,查询出来的结果已经变化了和time 1、time 3已经不一致了,不满足ACID的隔离性。

5,SELECT ... FOR UPDATE && SELECT ... LOCK IN SHARE MODE

默认情况下,innodb存储引擎的select操作使用一致性非锁定读,但是在某些情况下,需要对读操作进行加锁。Innodb存储引擎对select语句支持2种添加锁操作;

SELECT ... FOR UPDATE 对于读取的行记录加一个X排它锁,其他事务如果要对这些行进行dml或者select操作都会被阻塞。

SELECT ... LOCK IN SHARE MODE 对于读取的行记录添加一个S共享锁。其它事务可以向被锁定的行加S锁,但是不允许添加X锁,否则会被阻塞。

对于一致性 非锁定读,即使读取的行数已经被SELECT ... FOR UPDATE了,但是也是可以进行读取的。

PS:… FOR UPDATE以及LOCK IN SHARE MODE必须在一个事务中,如果事务commit了,锁也就释放了,所以在使用的时候务必加上begin;start transaction或者set autocommit=0;

例子如下:

会话A:开启事务,执行LOCK IN SHARE MODE;锁定

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM t1 WHERE a=1 LOCK IN SHARE MODE;

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

| a | b | c |

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

| 1 | c0 | c2 |

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

1 row in set (0.00 sec)

mysql>

同时在另外一个窗口开启会话B,执行dml操作

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> update t1 set a=111 where a=1;

…这里会卡住,没有信息。

再开启一个会话C,查询INNODB_LOCKS、INNODB_TRX、INNODB_LOCK_WAITS表,就会看到锁的详细信息:

mysql> select * from INNODB_LOCKS;

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

| lock_id | lock_trx_id | lock_mode | lock_type | lock_table | lock_index | lock_space | lock_page | lock_rec | lock_data |

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

| 3015708:797:3:2 | 3015708 | X | RECORD | `test`.`t1` | PRIMARY | 797 | 3 | 2 | 1 |

| 3015706:797:3:2 | 3015706 | S | RECORD | `test`.`t1` | PRIMARY | 797 | 3 | 2 | 1 |

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

2 rows in set (0.00 sec)

mysql>

mysql> select * from INNODB_LOCK_WAITS;

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

| requesting_trx_id | requested_lock_id | blocking_trx_id | blocking_lock_id |

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

| 3015708 | 3015708:797:3:2 | 3015706 | 3015706:797:3:2 |

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

1 row in set (0.00 sec)

mysql>

mysql> SELECT it2.`trx_id` AS waiting_trx_id, it2.`trx_state` AS waiting_trx_status,it2.`trx_mysql_thread_id` AS waiting_thread,it2.`trx_query` AS waiting_

首页 上一页 1 2 3 4 5 下一页 尾页 4/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇删除万网锋云主机默认Apache与MyS.. 下一篇MySQL触发器trigger之foreachrow

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·工业机器人TCP校准中 (2025-12-25 05:19:17)
·opc 通讯协议与 TCP (2025-12-25 05:19:15)
·labview中tcp/ip通信 (2025-12-25 05:19:13)
·新书介绍《Python数 (2025-12-25 04:49:47)
·怎么利用 Python 进 (2025-12-25 04:49:45)