通过Java运行“最初未记录更改表<表名>”时出现错误

时间:2018-10-06 14:43:31

标签: java jdbc db2 database-administration

我需要删除表中的数百万条记录,但是我需要注销事务日志,因为我使用的是最初未记录的Alter Table,但它引发了错误并且使表不可访问。表中没有分区,但表包含索引和序列。自动提交也关闭。 错误:DB2 SQL错误:SQLCODE = -911,SQLSTATE = 40001,SQLERRMC = 68,DRIVER = 3.65.77

仅在通过Java运行时才获得上述错误,而从客户端运行时则没有任何错误。 需要知道在所有情况和情况下查询都可能失败,或者在运行此查询之前需要确保哪些条件。如何在代码中处理这种情况。

1 个答案:

答案 0 :(得分:1)

在寻求有关Db2的帮助时,请始终对Db2服务器的版本和平台(Z / OS,i系列,Linux / Unix / Windows)提出疑问,因为答案可能取决于这些事实。

带有sqlerrmc 68的sqlcode -911是一个锁定超时。这不是僵局。你的工作 可能不是唯一同时访问表的作业。监视功能和管理视图可让您随时查看存在哪些锁(例如SNAPLOCK和SNAP_GET_LOCK表函数以及许多其他锁)。

有关以下建议的详细信息,请参考Db2知识中心,以进行自我教育。

对于您的事务而言,将表初始置于未记录状态是很高的风险,尤其是如果您是新手,因为如果事务失败,则可能会丢失整个表。

如果您坚持使用该方法,请采取预防措施并排练及时的恢复时间,以防您的行为造成损害。仔细验证备份和恢复步骤。

在禁用自动提交的情况下,可以将表锁定为独占模式,但是如果目标表是热表,则可能导致生产中断。如果您拥有相关权限,也可以强制关闭持有锁的应用程序。

如果在-911几乎不可避免的情况下尝试更改该表时有任何其他运行作业(即不是您自己的代码)正在访问该表。您的方法可能不明智。

可以通过其他方式实现批量删除,这取决于您要权衡的范围。 这是一个常见问题。它也不是RDBMS特定的。 考虑做更多的研究,因为这是一个广泛讨论的话题。

批量删除的替代方法包括:

  • 对已记录的删除进行批处理,每批提交一次,批量大小可调 (以确保避免出现-964事务日志已满的情况)。 这需要编程一个循环,您应该考虑“设置当前超时不等待” 以及稍后自动重试任何失败的批次(例如,失败的批次 由于锁)。这种方法产生了 缓慢而逐步地删除行,但增加了并发性。您正在交易 执行时间过长,对其他正在运行的作业的影响最小。

  • 创建一个相同的影子表,仅在其中插入您要插入的行 希望保持。然后在目标表上立即使用truncate table ... (这是未记录的操作) 最后将保留的行从影子表还原到目标表。 一种不太安全的变化是仅导出要保留的行,然后 导入替换

  • 取决于Db2许可证和清除频率,将数据(或某些数据)迁移到范围分区表中,并使用detach可能是更好的长期解决方案

有关上述建议的详细信息,请参考在线Db2知识中心。