无法同步数据库状态

Posted

技术标签:

【中文标题】无法同步数据库状态【英文标题】:Could not synchronize database state 【发布时间】:2014-11-29 15:58:29 【问题描述】:

我有一个 Java 类 ClassA,这个类定义了休眠映射。 在代码的某处,我需要检索保存在数据库中的此类的所有实例:

public List<ClassA> getAllClassA()
    Criteria crit = getSession().createCriteria(ClassA.class);
    return crit.list();

allA = getAllClassA();

稍后我将删除一些对象,同时更新其他对象:

public void removeItem() 
    Iterator<ClassA> it = allA.iterator();
    while(it.hasNext())
        ClassA cA = it.next();
        if(cA.hasCondition())
            dao.remove(cA);
            it.remove();
        
        else 
            cA.update();
        
    
    dao.update(allA);

//this is in another class
public void update(List<ClassA> allA) //dao.update
    for(ClassA cA: allA)
        getSession().saveOrUpdate(cA);
    

发生的情况是数据库已正确更新(并删除了所需的对象),但它也吐出以下错误:

错误 org.hibernate.event.def.AbstractFlushingEventListener.performExecutions:324 - 无法将数据库状态与会话 org.hibernate.StaleStateException 同步:批量更新返回意外 来自更新 [0] 的行数;实际行数:0;预计:1

我知道 Stack Overflow 上还有其他类似的问题,但它们似乎是由不同的条件引起的,在这种情况下没有用。

有什么想法吗?

【问题讨论】:

【参考方案1】:

optimistic locking 机制可防止由于并发请求而丢失更新。如果您说数据库已正确更新,则意味着其他一些线程可能已尝试更新您刚刚删除的某些实体。

总是有遇到这种情况的风险。大多数情况下最好放弃请求并从最新的数据库实体状态重新启动流程。

【讨论】:

谢谢,我发现这个答案很有用(因此赞成),但最后我设法通过颠倒更新和删除的顺序来解决它(见我的答案)【参考方案2】:

我不知道为什么,但是如果在更新之后执行删除,问题就消失了:

public void removeItem() 
    Iterator<ClassA> it = allA.iterator();
    ClassA toRemove = null; 
    while(it.hasNext())
        ClassA cA = it.next();
        if(cA.hasCondition())
            toRemove = cA;
            it.remove();
        
        else 
            cA.update();
        
    
    dao.update(allA);
    if(toRemove!=null)dao.remove(toRemove);

【讨论】:

以上是关于无法同步数据库状态的主要内容,如果未能解决你的问题,请参考以下文章

无法将数据库状态与会话同步

无法将数据库状态与 Grails Hibernate 中的会话错误同步

Aways on故障系列之一:所有的从数据库无法同步

Aways on故障系列之二:从数据库中有一台无法同步

mysql 主主同步两边的slave 状态都正常,但是数据却不一致

有道云笔记如何同步?