Java 为事务编写代码的正确方法是什么?

Java 为事务编写代码的正确方法是什么?,java,mysql,multithreading,transactions,deadlock,Java,Mysql,Multithreading,Transactions,Deadlock,当从多个线程或进程对同一数据库和表执行事务时,是否会出现以下类型的错误: 超过锁定等待超时;尝试重新启动事务 来自MySQL? 我的理解是,这并不表示死锁,也不表示由于昂贵的操作而导致的阻塞。 在我的例子中,我注意到代码结构如下: BEGIN DELETE FROM TableA where pk = X DELETE FROM TableC where colA = X DELETE FROM TableD where colA = X DELETE FROM TableE w

当从多个线程或进程对同一数据库和表执行事务时,是否会出现以下类型的错误:

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

来自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问题,因为这是我的首选语言)。

你说得对——这与死锁不同

innodb\u lock\u wait\u timeout
系统变量确定innodb在放弃之前等待获取行锁的时间

您的多个线程很可能需要互相等待,因此在本例中,您可能会重新考虑多个线程是否是实现您要完成的任务的有用方法


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

有没有理由不使用外键和级联删除?@X.L.Ant:这是当前的设计,我无法更改它。但我认为同样的问题也会出现,因为级联删除也是“冗长”的操作。是的,我同意。这只是出于好奇。但我不会在大量的行中进行操作。我有20个线程,每个线程在一个事务中从4个表中删除一行。也就是说,我为20个线程中的每一个线程都有20000个主键,每个线程都在OP的代码段中为每个PKs运行事务。如果单独运行一个事务,需要多长时间?我没有添加任何计时器,但查看控制台我记录了什么,我可以看到,根据日志,每个线程似乎都删除了一条“逻辑”记录,即在不到一秒钟的时间内完成了事务。当然,日志是“乱写”的,线程一个接一个地写