我正在寻找一种从 Java 6 应用程序中处理数据库死锁的好策略;几个并行线程可能同时写入同一个表。如果数据库 (Ingres RDMBS) 检测到死锁,它将随机终止其中一个会话。
考虑到以下要求,什么是处理死锁情况的可接受技术?
- 总经过时间应保持尽可能小
- 终止会话将导致显着(可测量的)回滚
- 时间线程无法相互
通信,即策略应该是自治的
到目前为止,我想出的策略是这样的:
short attempts = 0;
boolean success = false;
long delayMs = 0;
Random random = new Random();
do {
try {
//insert loads of records in table 'x'
success = true;
} catch (ConcurrencyFailureException e) {
attempts++;
success = false;
delayMs = 1000*attempts+random.nextInt(1000*attempts);
try {
Thread.sleep(delayMs);
} catch (InterruptedException ie) {
}
}
} while (!success);
它可以以任何方式改进吗?例如等待固定数量(幻数)的秒数。是否有不同的策略可以产生更好的结果?
注意:将使用几种数据库级技术来确保死锁在实践中非常罕见。此外,应用程序将尝试避免调度同时写入同一个表的线程。上述情况只是“最坏的情况”。
注意:插入记录的表组织为堆分区表,没有索引;每个线程都会在自己的分区中插入记录。