在包exec期间不允许DML操作

时间:2015-02-27 15:53:39

标签: java oracle jdbc plsql

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

所以,首先,我会解释这个想法。

1 - 我有一个java应用程序,它使用jdbc在我的数据库(Oracle DB)中插入数据。

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

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

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

5 - 此套餐计划每天执行2,3次

所以,我的问题是当转换任务开始时,我想阻止新的DML操作。然后,当转换停止时,应该在导出表中再次插入应该在该时间内插入/更新的所有新数据。

我采取了两种方法:

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

2 - 锁定表格但我没有那么多使用它的经验。我的主要问题是,我可以在jdbc中强制执行DML操作,等待锁定完成吗?还没有尝试过,但是在这里和那里读取了一些引发了lockwaittimeout异常之类的东西。

更有经验的人可以给我一些建议吗?

对我想做的事情有任何疑问只会问。

1 个答案:

答案 0 :(得分:1)

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

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

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