• mysql并发插入死锁


    前言

    开发中遇到多线程并发情况对数据批量插入

    主键id非雪花id,函数自增id

    原理分析

    两个事务都持有该行的 S 锁,期望获取 X 锁时被对方阻塞了。

    通俗讲就是并发插入出现相同的主键id导致阻塞

    在insert操作的时候就需要去拿 X 锁

    共享锁(Shared Lock)

    共享锁(Shared Lock),又称S锁、读锁。针对行锁。
    当有事务对数据加读锁后,其他事务只能对锁定的数据加读锁,不能加写锁(排他锁),所以其他事务只能读,不能写。

    主要为了支持并发读的场景,读时不允许写操作。

    加锁方式:
    select * from T where id=1 lock in share mode;
    释放方式:
    commit、rollback;

    排他锁(EXclusive Lock)

    排他锁(EXclusive Lock),又称X锁、独占锁、写锁。针对行锁。
    当有事务对数据加写锁后,其他事务不能再对锁定的数据加任何锁,又因为InnoDB对select语句默认不加锁,所以其他事务除了不能写操作外,照样是允许读的(尽管不允许加读锁)。

    主要为了在事务进行写操作时,不允许其他事务修改。

    加锁方式:
    自动:DML语句默认加写锁
    手动:select * from T where id=1 for update;
    释放方式:
    commit、rollback;

    锁消除

    删除改行记录(释放锁之后),其中一个事务将成功获取锁,从而执行成功,其他事务因死锁检测而回滚。

    扩展:MySQL官方声明-不同语句产生的锁

    SELECT … FROMis a consistent read,无锁
    SELECT … FOR UPDATEandSELECT … FOR SHAREstatements:对于唯一索引,只对需要锁定的记录上record lock,如果不是唯一索引就会加Next-key lock,同时会对不满足条件的第一个record的前面加上gap lock
    update和delete都2一样的策略
    insert比较不一样,需要重点说下
    首先,insert会对要插入的gap加insert intention gap lock,insert intention gap lock不像gap lock一样防止insert,insert intention gap lock互相之间可以共存,这样允许多个insert并发插入不同的位置

    其次,对于要插入的位置会加入排他锁

    多insert并发(至少3个),当插入的位置一样的时候(主键位置相同的时候),比如3个session都insert table id=x,其中第一个获得排他锁(行锁,写锁),其他两个session会产生duplicate-key error(后来的出现了重复的主键id),当duplicate-key error发生时,两个session都会将锁变化为共享锁,下一步获取排他锁(共享锁无法写入),然后第一个session rollback了,两个session互相持有共享锁,无法获得排他锁(两个一样行共享锁所以无法获取排他锁),导致死锁。

    s1 insert id =x 或者 s1 delete id = x

    s2 insert id = x

    s3 insert id = x

    s1 rollback

    replace和insert一样

    INSERT … ON DUPLICATE KEY UPDATE与insert不一样,当遇到 duplicate-key时,对于primary key获取排他记录锁,对于unique index获取Next-key lock,不会死锁

    优化性能和死锁问题的思路:

    尽量将热点行的操作延后
    控制并发度,加队列

    官方文档 不同语句产生死锁

  • 相关阅读:
    html5中让页面缩放的4种方法
    Beautiful Soup教程 转
    python 第三方模块 转 https://github.com/masterpy/zwpy_lst
    Windows安装Python图像处理库:PIL模块
    python常见的模块
    BeautifulSoup 常用方法
    服务器用户连接数设置
    如何查看IIS并发连接数【转】
    .net 时间戳和日期互转 【转】http://www.cnblogs.com/zhuiyi/p/5307540.html
    Python3学习笔记(urllib模块的使用)转http://www.cnblogs.com/Lands-ljk/p/5447127.html
  • 原文地址:https://www.cnblogs.com/tsangyi/p/16837829.html
Copyright © 2020-2023  润新知