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

问题描述 投票:1回答:2

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

@POST
@UnitOfWork
@Timed
public Event createEvent(Event event) {
    return eventDAO.updateOrCreate(event);
}

如果这是此特定用户ID或itemID的第一个事件,我们将分别创建用户或项目。这是项目的功能(用户相同):

public Item getOrCreate(Event event) {
    Item item = findOne(event.getItemId());
    if(item == null) {
        item = new Item();
        item.setItemId(event.getItemId());
        create(item);
    }
    return item;
}

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

user1 action1 item1
user2 action2 item1

似乎两者都尝试创建一个。从@UnitOfWork的documentation中,我们假定所有内容都将封装在事务中,因此不应发生这种情况。当我们添加了一个itemItem应该唯一的数据库约束时,我们得到一个PSQL异常“重复的键值违反了唯一约束...”。

我想念什么?

java hibernate postgresql transactions dropwizard
2个回答
0
投票

限制HTTP请求的事务不会阻止您所描述的问题。您尚未向数据库提供任何指示,以指示应使用什么来防止重复插入。除非存在数据库约束指示事件ID应该是唯一的,否则数据库无法说出它是在单独的请求中创建的同一实体。

我从描述中假设您给出的是您对数据库没有这样的约束。如果是这样,请添加一个,然后看看会发生什么。如果不是这种情况,您可能需要使用事件表所使用的架构来更新您的帖子。


0
投票

事务不会自动锁定该行,这是阻止另一个线程/请求所必需的。您需要使用LockMode.PESSIMISTIC_WRITE或类似的方法来完成此操作。

© www.soinside.com 2019 - 2024. All rights reserved.