Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从死锁中恢复_Java_Mysql_Deadlock_Database Deadlocks - Fatal编程技术网

Java 从死锁中恢复

Java 从死锁中恢复,java,mysql,deadlock,database-deadlocks,Java,Mysql,Deadlock,Database Deadlocks,我有一个2线程的进程从MySQL表访问数据。 由于MySQL的存在,我有时会陷入僵局 现在,我要做的是: 如果出现死锁,只需将所有行更新回其以前的状态,然后重新启动进程 但我怀疑,有些地方出了问题,因为在一个案例中,我想更新1300个ish数据,在死锁后,计数显示1700个ish 因此,一些数据可能通过调用流程的第二个实例进行了两次处理 我应该在重新启动进程之前杀死所有正在运行的线程吗 编辑: 我正在使用InnoDB,索引是在id上创建的。 线程应该获取limit 500中具有已处理标志“N”的

我有一个2线程的进程从MySQL表访问数据。 由于MySQL的存在,我有时会陷入僵局

现在,我要做的是: 如果出现死锁,只需将所有行更新回其以前的状态,然后重新启动进程

但我怀疑,有些地方出了问题,因为在一个案例中,我想更新1300个ish数据,在死锁后,计数显示1700个ish

因此,一些数据可能通过调用流程的第二个实例进行了两次处理

我应该在重新启动进程之前杀死所有正在运行的线程吗

编辑:

我正在使用InnoDB,索引是在id上创建的。 线程应该获取limit 500中具有已处理标志“N”的任何行,并对它们进行处理,然后将单个行更新为“Y”

我还更新了一个进程id,以指示哪个线程应该对哪些行执行操作

我仍然在resultset.updaterow()上陷入僵局

表:

create table Mail(
id integer not null auto_increment primary key,
from_eaddress varchar(50) not null,
to_address varchar(50) not null,
process_flg varchar(1) not null,
process_id varchar(50) default null,
time_stamp datetime default null,
index(id)
) engine=InnoDB;
最后是我的工作代码:
这似乎是一个事务性问题。在访问信息之前,必须在程序/控制器中使用必要的逻辑。如果您试图访问正在使用的行,您总是(不是有时)会看到此错误。有时会产生此错误,因为两个线程无法同时访问,但这是一种不正确的行为


注意:现代RDBMS自己管理内存。因此,您需要实现一个预防算法,例如

我遇到了mysql死锁问题,如下所述:

我最终的发现在我自己的回答中得到了解释


简言之,这些表没有按最佳方式编制索引,这意味着查询的运行速度要慢得多(而长时间运行的查询更可能导致死锁)。添加适当的索引完全消除了死锁问题。

我面临的死锁问题与事务相关

我所做的是将我的Update语句包装在一个事务块中,死锁消失了

        conn.setAutoCommit(false);// start transaction
        conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); 
        String sql2="update EmailQueue set process_flg='Y' where id="+id;
        //getting deadlocks here
        stmt=conn.createStatement();
        stmt.executeUpdate(sql2);
        conn.commit();// complete transaction
        conn.setAutoCommit(true);

通过
将所有行更新回它们以前的状态
您真正的意思是
回滚事务
,对吗?我建议您使用同步,最好避免死锁,而不是死锁,然后找到任何解决方案!!不,事实上我知道他们的状态应该是什么。所以,我只是把它们更新到那个状态。这只是更改时间戳。然后最好使用
事务
!!“如果您使用InnoDB或任何行级事务性RDBMS,则任何写事务都可能导致死锁,即使在完全正常的情况下也是如此。”请参阅:我将id作为主键,并在该id上设置索引。我在问题中添加了表结构。您的更新查询是什么样的?他们只查询ID吗?这就是我正在使用的。我提供了时间戳和进程id来匹配。从邮件中选择*时间戳=?进程_flg='N'和进程_id=?更新限制为500因为您唯一的索引是在ID上,并且您正在通过其他列进行查询。因此不使用索引,将扫描整个表。这是尽可能低效的。您应该在查询中的一列上有一个ID,或者多个列的复合索引。(取决于只有您知道的数据的性质)。这里我查询的是时间戳、进程flg和进程id。所以,索引应该是任意一个或它们的混合体??但是,所有3列都有重复的数据。例如,500行的时间戳是相同的。