【问题标题】:Mysql Deadlock in SELECT.. if nothing exists INSERTSELECT中的Mysql死锁..如果不存在插入
【发布时间】:2015-05-01 12:50:31
【问题描述】:

我有一个简单的拆分测试表:

CREATE TABLE `tracked_split_test_track_variant` (
  `tracked_split_test_id` int(10) unsigned NOT NULL,
  `track_id` bigint(20) unsigned NOT NULL,
  `variant` char(1) NOT NULL,  
  PRIMARY KEY (`tracked_split_test_id`,`track_id`),
  KEY `tracked_split_test_track_variant_1` (`tracked_split_test_id`),
  KEY `tracked_split_test_track_variant_2` (`track_id`),
  CONSTRAINT `fk_tracked_split_test_track_variant_2` 
    FOREIGN KEY (`track_id`) 
    REFERENCES `track` (`id`)
    ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `fk_tracked_split_test_track_variant_1` 
    FOREIGN KEY (`tracked_split_test_id`) 
    REFERENCES `tracked_split_test` (`id`) 
    ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8

variant 是随机的 A 或 B。

当系统询问“我应该向该用户显示哪个变体?”时我希望发生以下事情:

  • SELECT 属于当前tracktracked_split_testtracked_split_test_track_variant
  • 如果不存在记录,则使用随机变体创建一个新记录并INSERT

目前我在事务中运行SELECT 和(可选)INSERT 查询:

    SELECT * 
      FROM tracked_split_test_track_variant
     WHERE track_id = :track_id
       AND tracked_split_test_id = :tracked_split_test_id
FOR UPDATE

    INSERT 
      INTO tracked_split_test_track_variant
    VALUES (:track_id, :tracked_split_test_id, :variant)

我将FOR UPDATE 添加到SELECT,这样如果两个事务以相同的详细信息运行.. 我不会得到两次INSERT 尝试。

即使我尽快提交,但我现在却遇到了死锁。我做错了吗?

【问题讨论】:

    标签: mysql transactions deadlock


    【解决方案1】:

    由于元组在此事务之外是不可变的,因此我提出了使用显式命名锁的以下解决方案:

    SELECT GET_LOCK('tracked_split_test_track_variant-xxx-yyy',30);
    
    SELECT * 
      FROM tracked_split_test_track_variant
     WHERE tracked_split_test_id = :tracked_split_test_id
       AND track_id = :track_id
    
         [
    INSERT 
      INTO tracked_split_test_track_variant
    VALUES (:track_id, :tracked_split_test_id, :variant)
         ]
    
        DO RELEASE_LOCK('tracked_split_test_track_variant-xxx-yyy');
    

    其中xxxtracked_split_test_idyyytrack_id

    我很想看看是否有更好的解决方案。

    【讨论】:

      猜你喜欢
      • 2015-10-21
      • 2017-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多