以下第一个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

解决方案 »

  1.   

    补充:整个items表的结构为
    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
      

  2.   

    reviewid 这个字段不是主健,
    在条件中指定主健,mysql才会使用行锁,否则使用表锁
      

  3.   


    可是id才是主键啊,reviewid有重复的值的,那我能reviewid和id设置为联合主键么
      

  4.   

    联合主键也可以,其实联合主健的用法和主健都差不多使用row lock时,在查询条件中明确指明联合主健就可以,举个例子:表t(a,b,c), pk(a,b)select * from t where a=1 for update; //table lockselect * from t where a=1 and b = 2 for update;//row lockselect * from t where a=1 or b = 2 for update;//table lockselect * from t where c=66 for update;//table lock,这就是你刚开始遇到过的表锁的问题
      

  5.   

    还是不对,我重新建了个表试了下:-- ----------------------------
    -- 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;
    可以执行
      

  6.   

    建立了你的例子,插入几条记录.
    我的mysql没你这问题, 版本是5.0.41
      

  7.   

    楼主,不好意思,"在查询条件中明确指明主健",这句话我说错了,应该是索引
    看一下下面的blog,讲的比较清楚.
    http://brilon.javaeye.com/blog/433726一楼的情况,可能是下面的原因
    [引]
    (4)即便在条件中使用了索引字段,但是否使用索引来检索数据是由MySQL通过判断不同执行计划的代价来决定的,如果MySQL认为全表扫描效率更高,比如对一些很小的表,它就不会使用索引,这种情况下InnoDB将使用表锁,而不是行锁。因此,在分析锁冲突时,别忘了检查SQL的执行计划,以确认是否真正使用了索引。关于MySQL在什么情况下不使用索引的详细讨论,参见本章“索引问题”一节的介绍。