表output_values_center1
(和其他一些)继承output_values
。我会定期截断表output_values_center1
并加载新数据(在一个事务中)。在那个时候用户可以请求一些数据,他收到了错误信息。为什么会发生(选择查询请求只有一条记录)以及如何避免这样的问题:
2010-05-19 14:43:17 UTC ERROR: deadlock detected
2010-05-19 14:43:17 UTC DETAIL: Process 25972 waits for AccessShareLock on relation 2495092 of database 16385; blocked by process 26102.
Process 26102 waits for AccessExclusiveLock on relation 2494865 of database 16385; blocked by process 25972.
Process 25972: SELECT * FROM "output_values" WHERE ("output_values".id = 122312) LIMIT 1
Process 26102: TRUNCATE TABLE "output_values_center1"
答案 0 :(得分:1)
显然,目前尚不清楚您是否只查看上面链接的“联机帮助页”,查询父表会影响其后代。 SELECT命令的“联机帮助页”中的以下摘录说明了这一点:
答案 1 :(得分:0)
我会尝试这种(在伪代码中)截断:
#define NOWAIT_TIMES 100
#define SLEEPTIME_USECS (1000*100)
for ( i=0; ; i++ ) {
ok = query('start transaction');
if ( !ok ) raise 'Unable to start transaction!';
queries = array(
'lock table output_values in access exclusive mode nowait',
'truncate output_values_center1',
'commit'
);
if ( i>NOWAIT_TIMES ) {
// we will wait this time, as we tried NOWAIT_TIMES and failed
queries[0] = 'lock table output_values in access exclusive mode';
}
foreach q in queries {
ok = query(q);
if (!ok) break;
}
if (!ok) {
query('rollback');
usleep(SLEEPTIME_USECS);
} else {
break;
};
};
通过这种方式,您可以安全地避免死锁,因为父表将被独占锁定。用户将在截断运行时阻塞一小部分秒,并在提交后自动恢复。
但要做好准备,这可以在繁忙的服务器上运行几秒钟,因为当表正在使用时,锁将失败并重试。