【发布时间】:2015-03-17 17:08:14
【问题描述】:
我们有一个使用 dropwizard 编写的 rest API。 API 的一项功能是创建以下形式的事件三元组:userID - action - itemID 如果此 userID/itemID 组合还没有任何操作,我们将创建一个新事件。对应的资源函数有@UnitOfWork注解:
@POST
@UnitOfWork
@Timed
public Event createEvent(Event event) {
return eventDAO.updateOrCreate(event);
}
如果这是此特定 userID 或 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 中,我们假设所有内容都将包含在事务中,因此不应该发生这种情况。 当我们添加 itemId 应该是唯一的数据库约束时,我们得到一个 PSQL 异常“重复键值违反唯一约束...”。
我错过了什么?
【问题讨论】:
-
通过查看@UnitOfWork 代码,您可以看到它为每个请求创建新会话并且事务绑定到该会话。所以它不适用于你的情况。
-
但为什么不呢?我想要的不是一次交易和一次交易中的所有内容吗?
-
因为当您同时有 2 个请求时,您不在一个会话中,@UnitOfWork 将为您创建两个单独的会话。所以一个事务发生在一个会话中,而另一个事务发生在另一个会话中。
标签: java hibernate postgresql transactions dropwizard