2011-05-01 55 views
6

我要实现的,用户希望保持自己的搜索结果不变即使他们这样做,影响由返回的行相匹配的标准动作在Java CRUD应用程序的要求。饲养搜索结果在多个交易一致

困惑?好。让我给你一个熟悉的例子。在Gmail中,如果您对未读电子邮件进行高级搜索,则会显示匹配结果列表。点击一个条目,然后返回到搜索列表。会发生什么情况是您刚刚阅读了该条目,但它并未从原始结果集中消失。只有该行从粗体更改为正常。

我需要执行完全相同的行为,但应用程序的设计是这样一种方式,任何事务第一次坚持,然后UI重新查询数据库保持同步。应用程序的复杂性和数据库的大小使我无法在匹配行中进行简单的内存缓存并在db和内存中进行更改。

我想通过在Oracle数据库中创建一个中间表保存指针匹配记录和重新查询只有那些记录保持UI同步与数据解决在数据库级别上的问题。有任何想法吗?

回答

4

在Oracle中,如果你打开一个游标,该游标的结果是静态的,如果不考虑其他事务插入会出现在你的光标一排,或更新或删除,它在你的光标存在的行。然后

所面临的挑战是,如果你想要的结果打开游标时,从一致不关闭游标。

+0

但是你只能从游标读取一次......如果用户打算返回到搜索页面几次你需要打开多个游标。 – 2011-05-02 09:34:38

2

您可以使用闪回查询从过去读取数据。例如,select * from employee as of timestamp to_timestap('01-MAY-2011 070000', 'DD-MON-YYYY HH24MISS');

仅Oracle存储用于在有限的时间期间该历史信息。您需要查看您的保留设置; UNDO_RETENTION参数,UNDO表空间保留大小和适当的大小,以及LOB都有其自己的保留设置。

2

创建到数据库的两个连接。

设置第一个只读(使用SET TRANSACTION READ ONLY)从该连接做你的搜索,但要确保你从未结束,通过发出提交或回滚事务。

由于只读事务只能看到事务开始时的数据,因此第一个连接永远不会看到数据库发生任何更改 - 甚至不会发生任何更改。

然后,您可以在第二次连接中执行更新,而不会影响第一次连接的结果。

如果您不能使用两个连接,则可以通过使用自治事务的存储过程来实现更新,然后您可以在只有一个连接的情况下保持只读事务处于打开状态。

3

如果UI在数据库上维护单个会话,则一种解决方案是使用Oracle中的全局临时表。当您执行搜索时,将唯一ID插入GTT,然后UI仅查询GTT。

如果UI没有保持会话打开,你可以做同样的事情,但用普通的表。然后,当然,您只需添加一些清理代码即可从表中删除旧的搜索结果。

+0

这是一个聪明的主意,但需要一些调整来适应账单。数据访问通过连接池进行,因此GTT不适用。此外,建议的解决方案需要对数据访问层进行大量更改,从而导致不必要的副作用和性能问题。我想我需要使用触发器/存储过程魔术的组合来创建一个自填充的临时表,以便尽可能地避免代码中的数据保留复杂性。 – 2011-05-06 16:33:47