防止先前加载的实体在事务方法中更新

时间:2015-05-15 08:23:01

标签: java spring transactions

我的一项服务中有以下方法

@Override
@Transactional
public void createUserInfo(long userId, UserInfo userInfo) {
     User oldUser = userService.findUserById(userId);

     if (oldUser.infoIsTheSame(userInfo)) {
         return;
     }

     User updatedUser = userService.addUserInfo(userId, userInfo);      
     feedService.addFeed(FeedAction.INFO_UPDATE, oldUser, updatedUser);               
}

正如您所看到的,findUserById()addUserInfo()方法属于同一服务,标记为@Transactional本身。

userService.findUserById()createUserInfo()启动的同一事务中执行时,oldUser实例也会受到addUserInfo()内用户信息更改的影响(因为已加载的托管)实体处于同一交易中。)

所以我的问题是在服务方法调用后尝试addFeed()oldUserupdatedUser是相同的。

所以我的问题是,是否有办法改变,oldUser不会受到影响?

请注意,更改addUserInfo()以启动新交易不适合我,因为它在其他几个地方使用。

我还尝试复制oldUser(例如通过BeanUtils),但问题仍然存在。

Thnx寻求帮助。

1 个答案:

答案 0 :(得分:0)

使用EntityManager.detach()将实体与持久化上下文分离:

User oldUser = userService.findUserById(userId);

if (oldUser.infoIsTheSame(userInfo)) {
    return;
}

em.detach(oldUser); 
User updatedUser = userService.addUserInfo(userId, userInfo);      
feedService.addFeed(FeedAction.INFO_UPDATE, oldUser, updatedUser);