java - 关于事务中死锁的一个问题
怪我咯
怪我咯 2017-04-18 10:33:31
0
3
436

各位大神,小弟在这里先祝大家新年快乐。

小弟最近遇到一个关于mysql事务的问题,由于技术底子太单薄,希望借助各位大神的力量解决一下。

问题描述:

现在有一个账户,该账户是为集成我们服务的第三方平台分配的,作用基本是用于扣款。

在账户表中有一个次数(账户金额)的一个字段,账户表使用的存储引擎为InnoDB。

第三方平台的终端用户在使用他们的某一项功能时(其实该功能时我们提供的),第三方平台来调我们的接口,然后我们就减一次上面说的那个次数(账户金额)。

其实,说白了就是减库存的问题。

第三方平台用户数量很多,可能会大量并发的过来使用该功能。

我方平台的这个接口,加了事务控制,使用的是spring4.3.2 + mybatis3.4.1

上面说了,账户表的存储引擎为InnoDB。所以,每次调用我们接口,我们在扣款的时候,应该是开启了行级锁,把该账户的这条数据锁住了。以后来的扣款,估计都在等待。

最近经常报出异常为:
Deadlock found when trying to get lock; try restarting transaction

我现在很疑惑,为什么是死锁?而不是等待锁超时呢?
如果为:Lock wait timeout exceeded; try restarting transaction
我想我可能会理解,但是Deadlock我就不解了。

因为,第一个扣款线程进来先锁住那行记录,第二第三...的扣款线程就在外面一直等着。
第一个线程提交事务,释放InnoDB行级锁,第二个线程进来获取锁...应该为这样的顺序。
mysql有一个等待锁的超时时间,如果超时,那么线程直接timeout。

这里应该不存在死锁的情况啊?我理解死锁应该为,多方牵制导致锁永远也释放不掉。
我这种情况不是释放不掉啊,线程提交或回滚就释放了的啊?

各位大神,帮忙解释解释这个问题吧,停基础的,但是小弟...不会...

怪我咯
怪我咯

走同样的路,发现不同的人生

répondre à tous(3)
Peter_Zhu

Je ne connais pas grand-chose aux bases de données. Les verrous sont très compliqués. Votre situation peut impliquer une lecture en cours puis un verrouillage. Je recommande un article de blog sur l'analyse du traitement de verrouillage MySQL Après l'avoir lu, vous devriez être en mesure de dissiper votre confusion.

左手右手慢动作

https://dev.mysql.com/doc/ref...
Cela devrait être le même que cet exemple.

Peter_Zhu

Vous pouvez utiliser show innodb engine status pour vérifier les informations spécifiques de l'impasse. En même temps explan regardez le nombre de lignes utilisées par les instructions exécutées simultanément.

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal