【问题标题】:What is the proper way to write code for transactions?为事务编写代码的正确方法是什么?
【发布时间】:2014-12-13 20:50:28
【问题描述】:

当从多个线程或进程对同一个数据库和表进行事务处理时,通常会期望出现以下类型的错误:

超过锁定等待超时;尝试重启事务

来自 MySQL?
我的理解是,这并不表示死锁以及由于昂贵的操作而阻塞的情况。
就我而言,我注意到如下代码结构:

BEGIN  
DELETE FROM TableA where pk = X  
DELETE FROM TableC where colA = X  
DELETE FROM TableD where colA = X  
DELETE FROM TableE where colA = X  
DELETE FROM TableF where colA = X  
COMMIT  

为了获得更多上下文,我想从这些表中删除,以便更快,我通过分配批量 PK 而不是通过单个线程顺序执行来分隔多个线程中的删除。 所以基本上据我所知,不会出现死锁(如果我错了,请纠正我)。
所以我认为的问题是其中一个线程在尝试删除时被阻塞了太久。
似乎(也根据错误消息)我需要在应用程序级别处理这种情况。
所以我的问题是:在编写执行事务的代码时,通常需要期待这样的错误,例如等待几秒钟并重试事务几次然后可能放弃?
我不确定这是否是人们通常为交易编码的方式。
(注意:我将其标记为 Java,尽管它不是 Java 问题,因为它是我的首选语言)。

【问题讨论】:

  • 有理由不使用外键和级联删除吗?
  • @X.L.Ant:这是当前的设计,我无法更改。我会假设会出现同样的问题,因为级联删除也是“冗长”的操作
  • 是的,我同意。只是出于好奇。

标签: java mysql multithreading transactions deadlock


【解决方案1】:

你是对的——这和死锁不是一回事。

http://dev.mysql.com/doc/refman/5.6/en/innodb-parameters.html#sysvar_innodb_lock_wait_timeout

innodb_lock_wait_timeout 系统变量决定 InnoDB 在放弃之前等待获取行锁的时间。

您的多个线程很可能不得不相互等待,因此在这种情况下,您可能会重新考虑多线程是否对您要完成的任务有用。

通常,这些错误表明您的应用程序存在问题,因为如果行被锁定很长时间,这通常是一个问题的迹象——事务操作的最佳实践是进入、工作和尽快再次退出(提交或回滚)。显然,在对大量行进行操作时,这是不可能的,因此锁等待变得更有可能,因为需要相同排他行或索引锁的其他事务将不得不等待。

【讨论】:

  • 但我不会在大量行中执行操作。我有 20 个线程,每个线程在单个事务中从 4 个表中的每个表中删除一行。 IE。对于 20 个线程中的每一个,我都有 20000 个主键,并且每个线程都在 OP 的 sn-p 中为每个 PK 运行事务。
  • 有趣。如果单独运行其中一项交易需要多长时间?
  • 我没有添加任何计时器,但是查看控制台我记录的内容我可以看到,根据日志,每个线程似乎都删除了“逻辑”记录,即在不到一秒的时间内完成了事务.当然,日志是“乱七八糟”的,线程一个接一个地写
猜你喜欢
  • 2010-11-22
  • 1970-01-01
  • 1970-01-01
  • 2020-04-18
  • 1970-01-01
  • 2017-09-21
  • 1970-01-01
  • 2011-10-06
相关资源
最近更新 更多