mysql 锁表

 

http://blog.itpub.net/15480802/viewspace-755980/

 

用户必须拥有lock tables和select权限;

 

锁和写锁,优先处理写锁,除非使用了low_priority,但此选项对开启事务的innodb无效

 

一次只锁定一个表,但释放时同时执行

 

必须一次锁定所有要访问的表,否则会抱错,而information_schema下的表不需要显示锁定也可访问

LOCK TABLES t1 READ, t2 WRITE;

 

不能在一条sql中引用2次被锁定的表,即便使用也必须改用alias别名

 LOCK TABLE t WRITE, t AS t1 READ;

 

表锁仅阻止其他会话进行读写操作,若当前会话拥有某个表的锁,可执行drop table,但不可执行truncate table;

 

所有的单个update语句会默认获取表锁;

 

当对表进行insert delayed时不可对其添加表锁,否则insert delayed会报错,只因该insert由一个单独线程操作;

 

 

释放表锁

1  调用unlock tables,必须由执行Lock tables的同一会话执行

2  若会话再次调用lock tables,则其原本获取到的锁会被隐式释放

3   开启事务会隐含调用unlock tables,诸如start transaction

4   占有锁的会话一旦终止其锁会被自动释放,事务也会被回滚

5   rollback不会释放表锁

 

表锁与事务

Lock tables会隐式提交当前事务,unlock tables只有在已经调用lock tables的前提下才会隐式commit;

开启事务(诸如start transaction)会释放当前获取的表锁;

Flush tables with read lock获取的是全局锁,而非表锁

 

 

表锁与InnoDB

对于Innodb表,若要使用表锁,必须先设置autocommit=0且innodb_table_locks=1(默认),否则InnoDB无法侦测表锁而Mysql也无法感知行锁的存在;

且在事务提交后再unlock tables,如下例所示:

调用lock tables时,innodb引擎会获取内部表锁,然后mysql服务器获取表锁;commit时innodb释放内部表锁,unlock tables时mysql服务器才释放表锁;

如果autocommit=1,innodb不会获取内部表锁,极易导致死锁发生;

 

Lock tables与触发器

 

如果基表上建有触发器,且触发器引用到了其他表,则锁定基表时会连带锁定这些被引用的表

猜你喜欢

转载自ww111.iteye.com/blog/2262550