MySQL行级锁、表级锁、页级锁详细介绍 1、如果对读的响应度要求非常高,比如证券交易系统,那么适合用乐观锁,因为悲观锁会阻塞读 2、如果读远多于写,那么也适合用乐观锁,因为用悲观锁会导致大量读被少量的写阻塞 3、如果写操作频繁并且冲突比例很高,那么适合用悲观写独占锁 由于InnoDB 预设是Row-Level Lock,所以 只有「明确」的指定主键,MySQL 才会执行Row lock (只锁住被选取的数据) ,否则MySQL 将会执行Table Lock (将整个数据表单给锁住)。 举个例子: 假设有个表单products ,里面有id 跟name 二个栏位,id 是主键。 例1: (明确指定主键,并且有此数据,row lock) SELECT * FROM products WHERE id='3' FOR UPDATE; 例2: (明确指定主键,若查无此数据,无lock) SELECT * FROM products WHERE id='-1' FOR UPDATE; 例2: (无主键,table lock) SELECT * FROM products WHERE name='Mouse' FOR UPDATE; 例3: (主键不明确,table lock) SELECT * FROM products WHERE id<>'3' FOR UPDATE; 例4: (主键不明确,table lock) SELECT * FROM products WHERE id LIKE '3' FOR UPDATE; 注1: FOR UPDATE 仅适用于InnoDB,且必须在事务区块(BEGIN/COMMIT)中才能生效。 注2: 要测试锁定的状况,可以利用MySQL 的Command Mode ,开二个视窗来做测试。 ====================================================================== 页级:引擎 BDB。 表级:引擎 MyISAM , 理解为锁住整个表,可以同时读,写不行 行级:引擎 INNODB , 单独的一行记录加锁 表级,直接锁定整张表,在你锁定期间,其它进程无法对该表进行写操作。如果你是写锁,则其它进程则读也不允许 行级,,仅对指定的记录进行加锁,这样其它进程还是可以对同一个表中的其它记录进行操作。 页级,表级锁速度快,但冲突多,行级冲突少,但速度慢。所以取了折衷的页级,一次锁定相邻的一组记录。 MySQL 5.1支持对MyISAM和MEMORY表进行表级锁定,对BDB表进行页级锁定,对InnoDB表进行行级锁定。 对WRITE,MySQL使用的表锁定方法原理如下: 如果在表上没有锁,在它上面放一个写锁。 否则,把锁定请求放在写锁定队列中。 对READ,MySQL使用的锁定方法原理如下: 如果在表上没有写锁定,把一个读锁定放在它上面 否则,把锁请求放在读锁定队列中。 InnoDB使用行锁定,BDB使用页锁定。对于这两种存储引擎,都可能存在死锁。这是因为,在SQL语句处理期间,InnoDB自动获得行锁定和BDB获得页锁定,而不是在事务启动时获得。 行级锁定的优点: · 当在许多线程中访问不同的行时只存在少量锁定冲突。 · 回滚时只有少量的更改。 · 可以长时间锁定单一的行。 行级锁定的缺点: · 比页级或表级锁定占用更多的内存。 · 当在表的大部分中使用时,比页级或表级锁定速度慢,因为你必须获取更多的锁。 · 如果你在大部分数据上经常进行GROUP BY操作或者必须经常扫描整个表,比其它锁定明显慢很多。 · 用高级别锁定,通过支持不同的类型锁定,你也可以很容易地调节应用程序,因为其锁成本小于行级锁定。 (责任编辑:好模板) |