表锁一般没什么用,因为在事务中解除表锁的话会直接提交事务。
在事务中一般用到的是行锁,即innodb引擎支持。
共享锁例子:
#session1 会话1
start transaction;
SELECT * FROM feedback LIMIT 1,10;#无视
SELECT * FROM feedback LIMIT 1 FOR UPDATE;#只有加行锁的这行是锁定状态(FOR UPDATE)
COMMIT; #提交事务
#session2 会话2
start transaction;
update feedback set title='会话1行锁' where id=3;#该行无锁,直接执行
update feedback set title='会话1行锁' where id=1;#有锁,需要等待
COMMIT; #提交事务
排它锁例子:
#session1 会话1
start transaction;
UPDATE feedback set title='会话1排它锁' where id=1 FOR SELECT;#排它锁
COMMIT; #提交事务
#session2 会话2
start transaction;
update feedback set title='会话1行锁' where id=3;#该行无锁,直接执行
update feedback set title='会话1行锁' where id=1;#有锁,需要等待
COMMIT; #提交事务
因为之前用过oracle,知道利用select * for update 可以锁表。所以很自然就想到在mysql中能不能适应for update来锁表呢。
学习参考如下
由于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 ,开二个视窗来做测试。
由上面的InnoDB 已经交易区块引出两个问题。
1. what is InnoDB?
MySQL是我们比较常用的一种数据库软件。它有着诸多的优点,如开源的,免费的等等。其实它还有一个很好的特点,那就是有多种引擎可以供你选择。如果赛车手能根据不同的路况,地形随手更换与之最适宜的引擎,那么他们将创造奇迹。然而目前他们还做不到那样便捷的更换引擎,但是我们却可以!
所谓知己知彼方可百战不殆,要想将它们发挥到极致,首先我们应该来认识一下MySQL提供给我们的这几种引擎。
一般来说,MySQL有以下几种引擎:ISAM、MyISAM、HEAP、InnoDB和Berkley(BDB)。注意:不同的版本支持的引擎是有差异的。
进一步:
如何查看MySQL的当前存储引擎?
一般情况下,mysql会默认提供多种存储引擎,你可以通过下面的查看:
看你的mysql现在已提供什么存储引擎:
mysql> show engines;
以上说明我的mysql默认使用的InnoDB引擎,并且支持MyISAM,memory,archive,Mrg_myisam。
后面还跟着解释, InnoDB 的解释是:支持事务,行级别锁定,外键。
看你的mysql当前默认的存储引擎:
mysql> show variables like '%storage_engine%';
你要看某个表用了什么引擎(在显示结果里参数engine后面的就表示该表当前用的存储引擎):
ysql> show create table 表名;