假定有这样一张表
roleid 主键1
taskid 主键2
name现在有这样一个事务,
begin
;; 即首先删除所有当前roleid的行,然后插入
delete from tbl where roleid=11111111111;
insert into tbl values (11111111111 ,1,''),(11111111111 ,2,''),(11111111111 ,3,'');
end当多个role 同时执行此操作时, 出现了死锁 ( 注意 一个玩家只会操作自己的数据 )我猜测
好像 针对主键或索引的操作, 锁表时使用 行锁执行delete操作时 使用  表锁,(怀疑,where 条件里只根据roleid进行删除,此时使用表锁)
所以怀疑 当多个事务 同时想获得表锁时, 在这个过程中出现死锁, 不知对不对

解决方案 »

  1.   

    roleid 主键1
    taskid 主键2这两个字段是联合主键吧  一个表不能有两个主键的
      

  2.   

    表用的是什么存储引擎?MYISAM是表锁。 而INNODB是支持行锁和表锁的。
      

  3.   

    你是怎么判断出现思索的   是show engine innodb status看的吗
      

  4.   

    roleid taskid 联合主键
    innodb 
    用的show engine innodb status
      

  5.   

    同意LZ这个执行delete操作时 使用  表锁!
      

  6.   

    show engine innodb status中的LATEST DETECTED DEADLOCK贴出来看下
      

  7.   


    ------------------------
    LATEST DETECTED DEADLOCK
    ------------------------
    130703 17:17:09
    *** (1) TRANSACTION:
    TRANSACTION 1FA103, ACTIVE 0 sec, process no 26711, OS thread id 1772128576 inserting
    mysql tables in use 1, locked 1
    LOCK WAIT 3 lock struct(s), heap size 1248, 2 row lock(s)
    MySQL thread id 30018, query id 2718251 10.204.168.40 root update
    insert into role_share_base(`roleid`,`total`,`offline_time` ) values (1152921508901821512,0,20130703171709 )
    *** (1) WAITING FOR THIS LOCK TO BE GRANTED:
    RECORD LOCKS space id 202 page no 39 n bits 152 index `PRIMARY` of table `test`.`role_share_base` trx id 1FA103 lock_mode X locks gap before rec insert intention waiting
    Record lock, heap no 28 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
    0: len 8; hex 9000000100001c4a; asc        J;;
    1: len 6; hex 0000001f9ac4; asc       ;;
    2: len 7; hex 80000000e80110; asc        ;;
    3: len 4; hex 80000000; asc     ;;
    4: len 4; hex 51d3ec15; asc Q   ;;*** (2) TRANSACTION:
    TRANSACTION 1FA118, ACTIVE 0 sec, process no 26711, OS thread id 1700268352 inserting
    mysql tables in use 1, locked 1
    3 lock struct(s), heap size 1248, 2 row lock(s)
    MySQL thread id 35362, query id 2718347 10.204.168.40 root update
    insert into role_share_base(`roleid`,`total`,`offline_time` ) values (1152921508901821513,0,20130703171709 )
    *** (2) HOLDS THE LOCK(S):
    RECORD LOCKS space id 202 page no 39 n bits 152 index `PRIMARY` of table `test`.`role_share_base` trx id 1FA118 lock_mode X locks gap before rec
    Record lock, heap no 28 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
    0: len 8; hex 9000000100001c4a; asc        J;;
    1: len 6; hex 0000001f9ac4; asc       ;;
    2: len 7; hex 80000000e80110; asc        ;;
    3: len 4; hex 80000000; asc     ;;
    4: len 4; hex 51d3ec15; asc Q   ;;*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
    RECORD LOCKS space id 202 page no 39 n bits 152 index `PRIMARY` of table `test`.`role_share_base` trx id 1FA118 lock_mode X locks gap before rec insert intention waiting
    Record lock, heap no 28 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
    0: len 8; hex 9000000100001c4a; asc        J;;
    1: len 6; hex 0000001f9ac4; asc       ;;
    2: len 7; hex 80000000e80110; asc        ;;
    3: len 4; hex 80000000; asc     ;;
    4: len 4; hex 51d3ec15; asc Q   ;;
    原来那张表的 deadlock 日志 没了, ,不过这个也类似 。 。 
    事务 如下。
    ;; 如果只有roleid单主键
    begin
    delete from  role_share_base where roleid='111';
    insert into role_share_base(`roleid`,`total`,`offline_time` ) values (1152921508901821513,0,20130703171709 )
    end
      

  8.   

    delete中的roleid跟insert的roleid是不是一样的?
      

  9.   

    锁表试试
    LOCK TABLES role_share_base WRITE
    delete from  role_share_base where roleid='111';
     insert into role_share_base(`roleid`,`total`,`offline_time` ) values (1152921508901821513,0,20130703171709 )
     
    COMMIT;
    UNLOCK TABLES;建议在表中增加1字段(BZ),保存roleid状态,比如1有效0无效,roleid 替换为不可能的ID,在闲时再删除BZ=0的记录
    UPDATE role_share_base SET BZ=0,roleid='99999' where roleid='111';
      

  10.   

    关键是roleid 是主键 , 不能重复  。 。
    UPDATE role_share_base SET BZ=0,roleid='99999' where roleid='111';
    似乎不太好。
      

  11.   

    你的表中只有联合主键?
    roleid、 taskid 
      

  12.   

    show index from role_share_base ;贴出以供分析。
      

  13.   


    SHOW INDEX FROM role_share_base
    Table       Non_unique  Key_name  Seq_in_index  Column_name  Collation  Cardinality  Sub_part  Packed  Null  Index_type  Comment
    role_share_base  0  PRIMARY  1              roleid          A         2741          NULL      NULL          BTREE 
      

  14.   


    CREATE TABLE `role_share_info` (  `roleid` bigint(20) NOT NULL,  `type` int(11) NOT NULL DEFAULT '0' COMMENT '分享的种类',  `share_flag` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0,不可分享,1未分享,2已分享',  PRIMARY KEY (`roleid`,`type`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC
      

  15.   


    CREATE
        TABLE
            `role_share_base` (
                `roleid` bigint (20) NOT NULL
                ,`total` INT (11) DEFAULT NULL COMMENT '次数'
                ,`offline_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '上次下线时间'
                ,PRIMARY KEY (`roleid`)
            ) ENGINE = InnoDB DEFAULT CHARSET = utf8 ROW_FORMAT = DYNAMIC