【发布时间】:2013-06-15 01:59:50
【问题描述】:
我正在尝试创建一个新的数据库对象,保存它,然后检查保存是否成功。这样做的正确方法是什么:
class Document {
String externalId;
static constraints {
externalId(blank: false, unique: true);
}
}
def createDocuments(List<String> ids) {
Document.withTransaction() {
ids.each { String id ->
new Document(externalId: id).save();
}
}
// want to test here if transaction succeeded.
}
此事务可能会失败,因为其他用户可能同时创建了其中一个文档。因此,虽然一个实例是有效的(即它的 externalId 不为空),但它可能不是唯一的。但是不运行事务就无法判断。
怎么办?
更新
根据目前提供的答案,这是我的问题的症结所在:
如果我运行一个调用多个保存的事务,保存的对象何时可用于其他休眠会话?一些可能性:
-
save调用返回时 - 事务提交时
- 其他一些不确定的时间(大概在 #2 之前)
如果一个对象上的save 由于唯一性约束而失败,并且我回滚了事务,那么所有其他保存是否也会回滚,即使它们没有冲突?如果不是,那么将所有这些都包含在事务中的意义何在?
【问题讨论】:
-
.save 在成功保存的情况下返回持久对象本身。你可以让我们知道这一点。查看 grails 文档中的 save。
-
我认为事务在所有内容执行之前不会提交,所以我不清楚 save() 是否能够检测到重复违规。我不想在我的保存中指定
flush: true,因为我想优化性能:我想对一堆文档进行一次交易。 -
可以理解。但是这里的验证将在刷新到数据库之前由休眠处理,所以不使用
flush: true你应该能够有效地验证它。 -
我看不出它如何在提交事务之前验证唯一性。
-
这就是拥有像 Hibernate 这样的 ORM 持久层的全部意义所在。当您在约束中说
unique: true时,在保存休眠(会话)时会检查持久层中是否存在具有相同externalId的任何其他记录。如果找到,则休眠保存将在同一会话/事务中返回一条验证消息。根据该验证消息,您可以决定需要做什么。
标签: hibernate grails transactions