【问题标题】:How do I prevent duplicate rows from getting inserted?如何防止插入重复的行?
【发布时间】:2015-03-25 17:51:07
【问题描述】:

对于这个含糊的问题,我深表歉意,但我不知道如何用一句话来表达。这就是为什么我什至无法尝试谷歌搜索。

我有一个 DropWizard 资源,我使用 Hibernate 访问我的数据库。我有以下实体及其属性。

Trip
====
id
from_place
to_place
time
user_who_booked_it
trip_group_ref

TripGroup
=========
id
from_place
to_place
time

TripGroup 基本上将所有具有相同起点、终点和时间的旅行分组。这对以后的一些其他任务很有帮助。

创建Trip 对象的资源首先需要检查是否存在匹配的TripGroup,如果不存在则创建一个。这带来了一个问题。如果有并发请求,则可能会创建更多具有完全相同参数的 TripGroup 实例中的两个。

我该如何解决这个问题?

一种可能的解决方案是,我将检查和创建这些对象的代码部分封装在 synchronized 块中。但是,这可能不起作用,因为提交将在资源的方法完成后触发,即在 synchronized 块之外。

【问题讨论】:

    标签: hibernate dropwizard concurrent-programming


    【解决方案1】:

    复制约束确实应该在数据库级别设置。即使您可以处理应用程序代码中的所有并发问题,也不会阻止数据库客户端将重复的 TripGroup 行直接插入到您的表中。

    在 Dropwizard 中,如果您使用 Hibernate,您可以使用以下内容注释您的 TripGroup 模型类:

    @Entity
    @Table(name = "trip_group", uniqueConstraints = @UniqueConstraint(columnNames = {"id", "fromPlace", "toPlace", "time"}))
    public class TripGroup
    

    这将在您的数据库中创建一个约束,当违反它时您会收到错误消息。如果您使用JDBI,那么您需要手工创建表格或使用Liquibase

    【讨论】:

    • 那里有问题。是的,这将防止问题发生,但是,用户将收到 500 错误。如何捕获并重试?
    • 如果您有一个违反约束的副本,那么使用完全相同的参数重试是没有意义的。不确定我是否理解您的用例。
    • 当发生约束冲突错误时,DropWizard 会记录该错误并将 500 错误发送回客户端。我的问题是,DropWizard 是否有可能不再重试一次,而是使用相同的参数再次调用相同的资源?
    • 处理此问题的最佳方法是捕获异常并以 422 状态响应,因为具有该唯一字段的实体已经存在。
    猜你喜欢
    • 1970-01-01
    • 2023-03-06
    • 2015-08-07
    • 2016-08-24
    • 1970-01-01
    • 2016-02-19
    • 2012-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多