在 Packages exec 期间不允许 DML 操作

Not allow DML operations during Packages exec

我在这里需要一点帮助,因为我正在努力寻找解决我问题的最佳方法。我用谷歌搜索并没有任何有启发性的答案。

所以,首先,我将解释一下这个想法。

1 - 我有一个 java 应用程序,它使用 jdbc.

在我的数据库 (Oracle DB) 中插入数据

2 - 我的数据库在逻辑上一分为二。一部分包含 table 和导出信息(来自另一个应用程序),另一部分包含 table 代表一些报告。

3 - 我的 java 应用仅在导出中插入信息 table。

4 - 我开发了一些包,可以将数据从导出 table 转换为报告 table(生成一些报告)。

5 - 此包计划每天执行 2、3 次

所以,我的问题是当转换任务开始时,我想阻止新的 DML 操作。然后,当转换停止时,那段时间应该是 inserted/updated 的所有新数据都应再次插入到导出 table 中。

我有两种方法:

1 - 在转换期间将 DML 操作偏离到临时 table

2 - 锁定 tables 但我没有太多使用它的经验。我的主要问题是,我可以强制 jdbc 中的 DML 操作等到锁定完成吗?还没有尝试过,但是在这里和那里读到在一些抛出 lockwaittimeout 异常或类似的东西之后。

哪位有经验的可以给我一些建议吗?

对我正在尝试做的事情有任何疑问就问。

不要尝试将 table 锁定作为解决方案。可悲的是,这很常见,但很少有必要。一些想法:

  • 在转换开始时 select * 数据从 table 导出到 global_temp table。然后在那个临时 table
  • 上执行你的转换包
  • 创建一个 materialized view 类似 select * 来自导出 table 的数据。调查提交时刷新的选项,但似乎您需要在转换
  • 之前刷新 table
  • 分析您导出的数据。如果像许多其他情况一样,大多数数据一旦导入就永远不会改变。只需要分析新数据。为了帮助处理,添加一个名为 date_last_modified 的时间戳字段和 table 上的触发器。当更新一行时,然后更新 date_last_modified。这允许您选择 "only changed records"
  • 中可能的最小数据集
  • 您还应该研究使用 bulk collect 来优化您的光标。这将允许您一次获得一组记录,有点像某个时间点的数据快照
  • 我相信你想多了。如果您一次获取一组记录,那么 Oracle 将获取任何用户最后一次提交时的记录状态。如果您批量收集一组记录,它们将进入内存并再次代表某个时间点的状态。

让table对此感觉更舒服的最好方法是设置一个测试用例。在每个处理周期设置一个 sleeps 的游标。打开另一个会话并更改正在处理的数据。看看会发生什么....