我必须实现Java CRUD应用程序的要求,即使用户执行影响返回行匹配条件的操作,用户也希望保持搜索结果的完整性。
困惑?好。让我举个熟悉的例子。在Gmail中,如果您对未读电子邮件进行高级搜索,则会显示匹配结果列表。单击条目,然后返回搜索列表。发生的事情是您刚刚读取了该条目,但它并未从原始结果集中消失。只有该行已从粗体更改为正常。
我需要实现完全相同的行为,但应用程序的设计方式是首先保留任何事务,然后UI重新查询数据库以保持同步。应用程序的复杂性和数据库的大小使我无法对匹配的行进行简单的内存缓存,并在db和内存中进行更改。
我正在考虑通过在Oracle数据库中创建一个中间表来解决数据库级别的问题,该中间表包含指向匹配记录的指针并仅重新查询这些记录以使UI与数据保持同步。任何想法?
答案 0 :(得分:4)
在Oracle中,如果打开游标,则该游标的结果是静态的,无论另一个事务是否插入将出现在游标中的行,或更新或删除游标中存在的行。
如果你想要在光标打开时保持结果一致,那么挑战就是不要关闭光标。
答案 1 :(得分:3)
如果UI在数据库上维护单个会话,则一种解决方案是使用Oracle中的全局临时表。当您执行搜索时,将唯一ID插入GTT,然后UI只查询GTT。
如果UI不保持会话打开,您可以使用普通表执行相同的操作。然后,当然,您只需添加一些清理代码即可从表中删除旧的搜索结果。
答案 2 :(得分:2)
您可以使用闪回查询来读取过去的数据。例如,select * from employee as of timestamp to_timestap('01-MAY-2011 070000', 'DD-MON-YYYY HH24MISS');
Oracle仅在有限的时间段内存储此历史信息。您需要查看保留设置; UNDO_RETENTION参数,UNDO表空间保留gaurantee和正确的大小调整,以及LOB都有自己的保留设置。
答案 3 :(得分:2)
创建与数据库的两个连接。
将第一个设置为READ ONLY(使用SET TRANSACTION READ ONLY
)从该连接进行搜索,但确保从不通过发出提交或回滚来结束该事务。
由于只读事务只能看到事务开始时的数据,因此第一个连接永远不会看到对数据库的任何更改 - 甚至不会发生任何更改。
然后,您可以在第二个连接中进行更新,而不会影响第一个连接中的结果。
如果您不能使用两个连接,则可以通过使用自治事务的存储过程实现更新,然后您可以在您拥有的单个连接中保持只读事务处于打开状态。