Hibernate并发插入

时间:2011-05-17 12:06:58

标签: hibernate concurrency insert

我遇到了问题。我有一个带有Hibernate的App,它将XML文件中的数据加载到并发模式的表中。某些部分数据可能相同,可以从不同的线程插入。每个线程都在自己的长期交易中工作。当两个或更多踏板试图提交交易时会出现问题。例如,两个线程将记录插入到 NAME 字段中具有约束的表城市中。这意味着在flush()或commit()上发生ConstraintViolationException。我想自动处理这种冲突,并希望用旧的已插入对象替换新的问题对象。这可能吗?我在Hibernate中查看saveOrUpdate()和乐观版本控制。

3 个答案:

答案 0 :(得分:1)

我假设您使用MVCC-based DBMS之一。

如果事务隔离级别不高于READ COMMITTED,则可以通过在插入新查询之前发出查询以检查具有相同name的城市是否存在来减少冲突的可能性。

请注意,saveOrUpdate()在此无法提供帮助,因为name不是主键。另请注意,您根本无法阻止冲突(至少不使用某些特定于DBMS的功能),因为基本上它是write skew anomaly的一个示例,在基于MVCC的DBMS中无法阻止。

此外,如果导入XML文件的原子性并不重要,您可以将长事务分解为几个较短的事务,并在违反约束的情况下简单地重试它们。

答案 1 :(得分:0)

在这种情况下,我们使用'insertOrUpdate()'方法的约定,具有以下一般流程。事务在返回时由'insertOrUpdate()'方法的调用者提交:

public MyHibernateObject insertOrUpdate(MyHibernateObject newObj, Session s) {
    String name = newObj.getCityName();
    MyHibernateObject existingObj = getByCityName(name, s);
    if ( existingObj == null ) {
        s.saveOrUpdate(newObj);
        return newObj;
    } else {
        existing.copyImportantFields(newObj);
        s.saveOrUpdate(existing);
        return existing;
    }
}

答案 2 :(得分:0)

根据城市名称将输入数据分配给线程。