在 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 的游标。打开另一个会话并更改正在处理的数据。看看会发生什么....
我在这里需要一点帮助,因为我正在努力寻找解决我问题的最佳方法。我用谷歌搜索并没有任何有启发性的答案。
所以,首先,我将解释一下这个想法。
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 的游标。打开另一个会话并更改正在处理的数据。看看会发生什么....