Java Hibernate/Dropwizard:使用@UnitOfWork查找或创建不起作用

Java Hibernate/Dropwizard:使用@UnitOfWork查找或创建不起作用,java,hibernate,postgresql,transactions,dropwizard,Java,Hibernate,Postgresql,Transactions,Dropwizard,我们有一个用dropwizard编写的RESTAPI。API的一个功能是创建以下形式的事件三元组:userID-action-itemID 如果此userID/itemID组合尚未执行任何操作,我们将创建一个新事件。相应的资源函数具有@UnitOfWork注释: @POST @UnitOfWork @Timed public Event createEvent(Event event) { return eventDAO.updateOrCreate(event); } 如果这是此特定

我们有一个用dropwizard编写的RESTAPI。API的一个功能是创建以下形式的事件三元组:userID-action-itemID 如果此userID/itemID组合尚未执行任何操作,我们将创建一个新事件。相应的资源函数具有@UnitOfWork注释:

@POST
@UnitOfWork
@Timed
public Event createEvent(Event event) {
    return eventDAO.updateOrCreate(event);
}
如果这是此特定userID或itemID的第一个事件,我们将分别创建一个用户或一个项。这是项目的功能(用户相同):

问题是我们有重复的项(即,如果我们强制itemId是唯一的,则会出现错误)。如果我们在像这样的独立线程中有两个请求

user1 action1 item1
user2 action2 item1
似乎两者都试图创造一个。从@UnitOfWork的角度来看,我们假设一切都将被包装在一个事务中,因此这不应该发生。 当我们添加了一个itemId应该是唯一的数据库约束时,我们得到了一个PSQL异常“复制键值违反了唯一约束…”


我遗漏了什么?

绑定HTTP请求的事务不会阻止您描述的问题。您没有给数据库任何指示,说明它应该使用什么来防止双重插入。除非有一个数据库约束指示事件ID应该是唯一的,否则数据库无法判断它是在不同请求中创建的同一个实体


根据您给出的描述,我假设您对数据库没有这样的约束。如果是这样,添加一个,然后看看会发生什么。如果不是这样,您可能希望使用事件表所使用的架构更新post。

事务不会自动锁定行,这是阻止其他线程/请求所必需的。您需要使用或类似工具来完成此操作。

谢谢您的回答。我添加了关于约束的信息。通过查看@UnitOfWork代码,您可以看到它正在创建新会话的每个请求,并且事务绑定到该会话。所以这在你的情况下不起作用,但为什么不呢?不是我想要的在一个事务和每个会话中都有一个事务吗?因为当您同时有两个请求时,您不在一个会话中,@UnitOfWork将为您创建两个单独的会话。因此,一个事务在一个会话中发生,而另一个事务在另一个会话中发生。
user1 action1 item1
user2 action2 item1