首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
Coding
V2EX  ›  MySQL

MySql 两张表发生了死锁

  •  
  •   ShutTheFu2kUP · 57 天前 · 2034 次点击
    这是一个创建于 57 天前的主题,其中的信息可能已经有所发展或是发生改变。

    表 A

    a_id int (主键)
    a_name varchar
    

    表 B

    b_id int (主键)
    b_name varchar
    a_id int (代码维护的外键,有个单独的索引'idx_a_id')
    

    show engine innodb status

    1. 事务 1
    SQL: delete from b where a_id = 123
    等待锁: b 表的索引 idx_a_id
    
    1. 事务 2
    SQL: update a set a_name = 'xxx' where a_id = 123
    持有锁: b 表的索引 idx_a_id
    等待锁: a 表的索引 PRIMARY
    

    两张表的外键关系是代码维护的,为什么 a 还能持有 b 的锁,两个 SQL 的关系只有 a_id 是一样的,今年刚毕业,对底层确实不太了解,希望大佬解答一下原因和优化方式

    第 1 条附言  ·  56 天前

    因为这个事务里封装了多个SQL的调用,同时前端不知道因为什么原因在一秒内调用了N次接口,导致了并发操作导致了死锁。除了防止同时多次调用还有办法避免死锁吗?

    @Transational
    public void function() {
    
        delete from b where a_id = 123 // 调用执行该sql
    
        update a set a_name = 'xxx' where a_id = 123 // 调用执行该sql
        
    }
    
    第 2 条附言  ·  56 天前

    看了两天的文章,大概有了个推论

    函数

    @Transational
    public void function() {
    
        select * from a where a_id = 123 // 调用执行该sql
    
        update a set a_name = 'xxx' where a_id = 123 // 调用执行该sql
        
    }
    
    1. 两个事务T1,T2并发执行select语句,此时T1,和T2都拥有S锁
    2. 继续执行,T1要执行update,但是发现该行数据还有T2的S锁,所以等待T2释放S锁
    3. T2也要执行update,也发现改行有T1的S锁,所以等待T1的S锁释放,此时因为都在互相等待对象的锁释放,所以形成了死锁

    根据以上的推论写方法测试了一下,但是发现Java中@Transational内的方法select好像并没有加共享锁,有大佬看看是怎么个问题吗?

    目前尚无回复
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   949 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 23ms · UTC 21:06 · PVG 05:06 · LAX 13:06 · JFK 16:06
    ♥ Do have faith in what you're doing.