IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    想要加悲观锁可是数据行还不存在怎么办?

    Crazyant发表于 2015-08-04 09:00:13
    love 0

    两个并发事务想要对同一个KEY的数据进行更新,但是如果这个KEY的数据行还不存在的话,那么select .. for update当然不能锁住这行记录,想当然的想到,可不可以先insert一下,然后在悲观锁呢?

    那么引入了一个新的问题,如果两个并发事务同时insert的话,就会插入重复的数据,如果insert的unique key重复的话,第二个线程会报错的,有没有更优雅的方法?

    答案是MySQL innodb的INSERT … ON DUPLICATE KEY UPDATE语法;

    用法见官网文档:https://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html

    If you specify ON DUPLICATE KEY UPDATE, and a row is inserted that would cause a duplicate value in a UNIQUEindex or PRIMARY KEY, MySQL performs an UPDATE of the old row. For example, if column a is declared as UNIQUEand contains the value 1, the following two statements have similar effect:

    INSERT INTO table (a,b,c) VALUES (1,2,3)
      ON DUPLICATE KEY UPDATE c=c+1;
    
    UPDATE table SET c=c+1 WHERE a=1;
    

    使用ON DUPLICATE KEY UPDATE语法,第二条insert语句,会自动变成Update语句,而不会导致重复插入数据的BUG;

    做个简单的测试:

    CREATE TABLE `tcc` (
      `idx` INT(11),
      `typeid` INT(11),
      `value1` INT(11),
      `value2` INT(11),
      UNIQUE KEY(idx, typeid)
    ) ENGINE=INNODB DEFAULT CHARSET=utf8;
    
    -- 第一条SQL的执行,会新增一条数据,本SQL多次执行,效果相同,因为后续的操作,变成了UPDATE
    INSERT INTO tcc (idx, typeid, value1) 
    VALUES (1,2,3) ON DUPLICATE KEY UPDATE value1=3;
    
    -- 第二条SQL直接进行UPDATE,把新列的值update进去
    INSERT INTO tcc (idx, typeid, value2) 
    VALUES (1,2,4) ON DUPLICATE KEY UPDATE value2=4;

    产出结果只有一条:

    “idx” “typeid” “value1″ “value2″
    “1” “2” “3” “4”

    有了这个利器,那么代码中就可以直接insert.. on duplicate key update,这个SQL的执行能保证数据库中会存在记录,然后加上悲观锁,来保证不同的事务不会出现更新冲突情况;

    本文地址:http://www.crazyant.net/1835.html

    您可能也喜欢:

    Firefox数据采集插件大全

    数据采集利器-PHP用DOM方式处理HTML之《Simple HTML DOM》

    Python使用cookielib和urllib2模拟登陆新浪微博并抓取数据

    Python中的操作符重载

    疯狂的蚂蚁
    无觅


沪ICP备19023445号-2号
友情链接