从死锁中恢复
Recovery from deadlock
我有一个 2 线程进程从 MySQL table 访问数据。
由于 MySQL 有可能,我有时会陷入僵局。
现在,我准备好的是:
在死锁的情况下,只需将所有行更新回它们以前的状态,然后重新启动进程。
但我怀疑出了点问题,因为在一个案例中我想更新 1300 左右的数据,但在死锁后计数显示为 1700 左右。
所以,一些数据可能通过调用进程的第二个实例被处理了两次。
我应该在重新启动进程之前杀死所有 运行 线程吗?
编辑:
我正在使用 InnoDB 并在 id 上创建索引。
线程应该获取限制为 500 且带有已处理标志 'N' 的任何行并处理它们,然后将各个行更新为 'Y'.
我还更新了一个进程 ID,以指示哪个线程应该对哪些行执行操作。
我仍然在 resultset.updaterow()
上陷入僵局
Table:
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;
最后这是我的工作代码:
https://github.com/codezero10/MailQueue/tree/master
这似乎是一个交易问题。在访问信息之前,您必须在 program/controller 中使用必要的逻辑。如果您尝试访问正在使用的行,您总是(不是有时)会看到此错误。有时会因为两个线程不能同时访问而产生,但这是不正确的行为
注意:现代 RDBMS 自行管理其内存。因此,您需要实施一种预防算法,例如 Mutual exclusión。
我遇到了一个 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);
我有一个 2 线程进程从 MySQL table 访问数据。 由于 MySQL 有可能,我有时会陷入僵局。
现在,我准备好的是: 在死锁的情况下,只需将所有行更新回它们以前的状态,然后重新启动进程。
但我怀疑出了点问题,因为在一个案例中我想更新 1300 左右的数据,但在死锁后计数显示为 1700 左右。
所以,一些数据可能通过调用进程的第二个实例被处理了两次。
我应该在重新启动进程之前杀死所有 运行 线程吗?
编辑:
我正在使用 InnoDB 并在 id 上创建索引。 线程应该获取限制为 500 且带有已处理标志 'N' 的任何行并处理它们,然后将各个行更新为 'Y'.
我还更新了一个进程 ID,以指示哪个线程应该对哪些行执行操作。
我仍然在 resultset.updaterow()
上陷入僵局Table:
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;
最后这是我的工作代码: https://github.com/codezero10/MailQueue/tree/master
这似乎是一个交易问题。在访问信息之前,您必须在 program/controller 中使用必要的逻辑。如果您尝试访问正在使用的行,您总是(不是有时)会看到此错误。有时会因为两个线程不能同时访问而产生,但这是不正确的行为
注意:现代 RDBMS 自行管理其内存。因此,您需要实施一种预防算法,例如 Mutual exclusión。
我遇到了一个 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);