简体   繁体   English

分离的实体已传递以保留

[英]Detached entity passed to persist

CacheId aci = new CacheId();
aci.setId(cacheObject.getId());
aci.setSequence(cacheObject.getSequence());
Cache persisted = em.find(Cache.class, aci);
if (persisted == null){
    System.out.println("========== PERSISTING");
    em.persist(cacheObject);
}else{
    System.out.println("========== MERGING");
    em.merge(cacheObject);
}

Mean while im running my project another instance deletes the entry with current CacheId. 这意味着在运行我的项目时,另一个实例将删除具有当前CacheId的条目。 Now what i need to do is set the new value to the database with same cache id. 现在我需要做的是将新值设置为具有相同缓存ID的数据库。 But when i do a em.find() this does not return null. 但是,当我执行em.find()时,它不会返回null。 (but in the database entry is already deleted. So this will end up calling merge. And merge failed with trying to update 1 but updated 0... (但是数据库条目已被删除。因此,这将最终调用merge。并且合并失败,并尝试更新1但更新为0 ...

But if i stop checking the search and call persist always then i get "Detached entity passed to persist ". 但是,如果我停止检查搜索并始终调用持久化,那么我会收到“传递给持久化的独立实体”。 How can i work around this issue ? 我该如何解决这个问题?

You have a problem of concurrent access and the answer is locking . 您有并发访问问题,答案是锁定 If you use optimistic locking in your application, just catch the Exception and retry (a limited number or times). 如果您在应用程序中使用开放式锁定,则只需捕获Exception并重试(有限次数)。

You can also use the pessimistic locking pattern by using : 您还可以通过以下方式使用悲观锁定模式:

Cache persisted = em.find(Cache.class, aci, LockModeType.PESSIMISTIC_WRITE);

(or LockModeType.PESSIMISTIC_READ ). (或LockModeType.PESSIMISTIC_READ )。 The lock is obtained immediately from database, that is you will know immediately if the data has been removed. 该锁是立即从数据库获取的,也就是说,您将立即知道是否已删除数据。 And once the lock is obtained, no other transaction will be allowed to removed it. 并且一旦获得了锁,将不允许任何其他事务将其删除。

The only remaining race condition would be if two transaction try to create the same data. 唯一剩余的竞争条件是两个事务尝试创建相同的数据。

But BEWARE : the application should commit as soon as possible to release the lock to avoid potential deadlocks or unnecessary blocking of other transactions. 但是请注意:应用程序应尽快提交以释放锁,以避免潜在的死锁或不必要的其他事务阻塞。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM