0

我遇到了通过 Java Web 服务到达我们数据库的重复记录的问题,我认为这与 Oracle 处理线程有关。

使用我们构建的 iPhone 应用程序,用户可以将鸟类观察结果添加到他们在假期访问的新站点。他们在“新站点 A”(例如)创建了三个记录。iPhone 将这三个记录中的每一个都打包成单独的 JSON 字符串,其中包含相同的日期和位置详细信息。

在上传时,Web 服务会遍历每个 JSON 字符串。
迭代/观察 1. 它检查数据库以查看站点是否存在,如果不存在,则创建一个新站点并将观察结果添加到挂表中。
迭代/Obs 2. 该站点现在应该存在于数据库中,但在迭代 1 中的数据库站点检查未找到该站点,并且创建了第二个新站点。
迭代/Obs 3. 对现有站点的检查现在可以工作,第三个观察结果附加到现有站点之一。所以 Web 服务和数据库代码确实有效。

Web 服务在每次迭代结束时提交。

第二次迭代的原因是由于Java调用后Oracle提交延迟导致第二次迭代没有在数据库中找到新站点,因此在迭代1真正完成时它已经开始处理迭代2,或者是否有可能Oracle 在单独的线程上运行每个迭代?

我们考虑的一种解决方案是在 Web 服务中使用 Thread.sleep(1000),但我宁愿不惩罚 iPhone 用户。

感谢您的任何帮助,您可以提供。伊恩

4

2 回答 2

6

对我来说,这听起来像是一种比赛条件。可能您的观察 1 和 2 到达彼此非常接近,因此当 2 到达时 1 仍在处理中。Oracle 符合 ACID,这意味着您的观察 2 事务无法看到事务 1 中所做的更改,除非该更改在事务 2 开始之前完成。

如果你需要一个检查然后创建的功能,你最好在后端的一个点上同步它。

此外,在您的数据库中添加一个约束,以不惜一切代价避免重复。

于 2013-04-03T11:49:50.350 回答
1

这不是 Oracle 问题。Thread.sleep 将是一个糟糕的解决方案,尤其是因为您不知道根本原因。

你的描述令人困惑。三个 JSON 字符串是否在一个 HTTP 请求中发送?订单是否重要,或者处理其中任何一个是否首先为随后的订单设置新位置?

什么是“吊桌”?

这是位置和观察之间的亲子关系吗?所以工作单元是在父表中插入一个新位置,然后在子表中引用父表中的三个观察?

我认为这是您的查询及其编写方式的问题。我可以向你保证,Oracle 对于这个小问题已经足够快了。如果它可以处理纳斯达克交易率,它就可以处理您的网站。

我会这样写你的 DAO 进行观察:

public interface ObservationDao {
    void saveOrUpdate(Observation observation);
}

将所有逻辑保留在 DAO 中。在 servlet 之外对其进行测试并将其放在一边。一旦你让它工作,你就可以专注于网络应用程序。

于 2013-04-03T11:46:00.880 回答