以下第一个session:
mysql> begin;
Query OK, 0 rows affectedmysql> select id from items where reviewid=37 for update;
+--------+
| id |
+--------+
| 120041 |
| 120042 |
| 120043 |
| 120044 |
| 120045 |
+--------+
5 rows in set================================================
以下第二个session
mysql> begin;
Query OK, 0 rows affectedmysql> update items set getsum=123 where reviewid=36;为什么第二个session运行到这里会被锁住呢,第一个session锁的是reviewid为37的行啊,reviewid已经加了索引,直到第一个session运行commit后,第二个session才出现以下提示:
Query OK, 5 rows affected
Rows matched: 5 Changed: 5 Warnings: 0
mysql> begin;
Query OK, 0 rows affectedmysql> select id from items where reviewid=37 for update;
+--------+
| id |
+--------+
| 120041 |
| 120042 |
| 120043 |
| 120044 |
| 120045 |
+--------+
5 rows in set================================================
以下第二个session
mysql> begin;
Query OK, 0 rows affectedmysql> update items set getsum=123 where reviewid=36;为什么第二个session运行到这里会被锁住呢,第一个session锁的是reviewid为37的行啊,reviewid已经加了索引,直到第一个session运行commit后,第二个session才出现以下提示:
Query OK, 5 rows affected
Rows matched: 5 Changed: 5 Warnings: 0
CREATE TABLE `items` (
`id` int(11) NOT NULL auto_increment,
`reviewid` int(11) default '0',
`query` varchar(100) default NULL,
`query_cat` varchar(100) default NULL,
`title` varchar(100) default NULL,
`url` varchar(100) default NULL,
`pic_url` varchar(100) default NULL,
`sell_count` varchar(10) default NULL,
`credit` varchar(10) default NULL,
`nick` varchar(30) default NULL,
`good_rate` varchar(10) default NULL,
`getsum` int(11) unsigned default '0'
`getusers` varchar(100) default ',',
PRIMARY KEY (`id`),
KEY `aaa` (`reviewid`)
) ENGINE=InnoDB AUTO_INCREMENT=120051 DEFAULT CHARSET=gbk
在条件中指定主健,mysql才会使用行锁,否则使用表锁
可是id才是主键啊,reviewid有重复的值的,那我能reviewid和id设置为联合主键么
-- Table structure for `book`
-- ----------------------------
DROP TABLE IF EXISTS `book`;
CREATE TABLE `book` (
`id` int(11) NOT NULL auto_increment,
`num` int(11) default NULL,
PRIMARY KEY (`id`),
KEY `asd` (`num`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk;-- ----------------------------
-- Records of book
-- ----------------------------
INSERT INTO `book`(num) VALUES (11);
INSERT INTO `book`(num) VALUES (11);
INSERT INTO `book`(num) VALUES (11);
INSERT INTO `book`(num) VALUES (22);
INSERT INTO `book`(num) VALUES (22);
然后在一个seesion里运行
begin;
select * from book where num=11 for update;
在另一个session里运行update book set num=1234 where num=22;
可以执行
我的mysql没你这问题, 版本是5.0.41
看一下下面的blog,讲的比较清楚.
http://brilon.javaeye.com/blog/433726一楼的情况,可能是下面的原因
[引]
(4)即便在条件中使用了索引字段,但是否使用索引来检索数据是由MySQL通过判断不同执行计划的代价来决定的,如果MySQL认为全表扫描效率更高,比如对一些很小的表,它就不会使用索引,这种情况下InnoDB将使用表锁,而不是行锁。因此,在分析锁冲突时,别忘了检查SQL的执行计划,以确认是否真正使用了索引。关于MySQL在什么情况下不使用索引的详细讨论,参见本章“索引问题”一节的介绍。