我在这里需要一些帮助,因为我在努力寻找最佳解决方案来解决我的问题。我用谷歌搜索,没有任何启发性的答案。
所以,首先,我将解释这个想法。
1-我有一个Java应用程序,它使用jdbc在我的数据库(Oracle DB)中插入数据。
2-我的数据库在逻辑上分为两部分。一部分包含带有导出信息的表(来自另一个应用程序),另一部分带有表示某些报告的表。
3-我的Java应用程序仅在导出表中插入信息。
4-我已经开发了一些软件包,可以将数据从导出表转换为报告表(生成一些报告)。
5-该软件包计划每天执行2次,每次3次
所以,我的问题是,当转换任务开始时,我想阻止新的DML操作。然后,当转换停止时,应该在该时间段内插入/更新的所有新数据都应再次插入导出表中。
我以两种方式进行强硬:
1-在转换期间,DML操作将移到临时表
2-锁定表,但我没有太多使用此功能的经验。我的主要问题是,我可以强制jdbc中的DML操作等待锁完成吗?还没有尝试过,但是在这里读到那之后会抛出一个lockwaittimeout异常之类的东西。
有经验的人可以给我一些建议吗?
对我要做什么的任何疑问都可以问。
最佳答案
不要尝试锁定表作为解决方案。可悲的是,这很普遍,但很少有必要。只是一些想法:
在转换开始时,从导出表中选择*数据到global_temp table中。然后在该临时表上执行转换包
创建materialized view,例如从导出表中选择*数据。研究在提交时刷新的选项,但似乎您需要在转换之前刷新表
分析您的导出数据。如果像其他许多情况一样,大多数数据一旦导入就永远不会改变。仅需要分析新数据。为了帮助处理,在表上添加了一个名为date_last_modified的时间戳字段和一个触发器。更新一行后,请更新date_last_modified。这使您可以选择“仅更改的记录”中可能的最小数据集
您还应该调查使用bulk collect来优化光标。这将使您一次获得一组记录,并在某个时间点获得数据快照
我相信您正在考虑这个问题。如果一次获取一组记录,那么Oracle将获得任何用户最近一次提交时的记录状态。如果您批量收集一组记录,它们将进入内存,并再次代表某个时间点的状态。
对此感到更舒服的最好方法是设置一个测试用例。在每个处理周期中设置一个sleeps游标。打开另一个会话并更改正在处理的数据。走着瞧吧....