MySQL死锁可能吗?

时间:2015-10-19 11:49:32

标签: java mysql spring hibernate deadlock

我有一个在MySQL,Hibernate和Spring管理的事务上运行的java应用程序。 有一个特定的交易让我担心一点。我尝试设置一些并发测试环境(使用ApacheBench),测试似乎没问题,但我还是有些疑惑......
事务逻辑沿着这些方向(使用混合的sql +伪代码,为简洁起见):

updated = 0;

// lock counter row, if exists
selected = select x from tbl1 where [composite PK match] FOR UPDATE;

if(selected == null) {
    // Record does not exist... I thought this might be a good idea, as there will be only 
    // one insert for the given PK daily and many subsequent updates (rather do this than 
    // forcing 'insert...on duplicate key update' constantly?)
    updated = insert into tbl1 values(...) on duplicate key update cnt = cnt + 1;
} else {
    // Record exists, just increment the counter.
    updated = update tbl1 set cnt = cnt + 1;
}
return updated;

tbl1是这样的:

create table tbl1 (
  `a_id` int(11) NOT NULL,
  `b_id` int(11) NOT NULL,
  `c_id` int(11) NOT NULL,
  `day` date NOT NULL,
  `cnt` int(11) DEFAULT '0',
  PRIMARY KEY (`a_id`,`b_id`,`c_id`,`day`)
) ENGINE=InnoDB;

事务隔离是MySQL的默认值(REPEATABLE READ)。

对我来说最重要的是:

  1. 以上代码是否在高度并发的环境中导致死锁?
  2. ...我还想添加两个相关的子问题:

    1. 在这个表上增加一个计数器:update tbl1 set c = c + 1 where [match row by composite PK]线程安全/原子/一致吗?
      根据我的测试,它是。根据{{​​3}},它可能取决于......如果是,我猜上面的逻辑可以进一步优化/简化,因此它不会使用select...for update(我只是为了安全而添加它侧)。

    2. 如果select...where...for update作为第一个语句在事务中执行,但没有匹配WHERE子句的记录,那么这可能会导致一些隐藏的行级锁定,之后的DML语句可能会使用相同的匹配条件(如示例中)执行,以及这可能会如何影响其他并发事务?

0 个答案:

没有答案