我花了整个晚上试图弄清楚,此时我很绝望。我的 Grails 2.1.0 项目中有服务类。它对 Web 服务执行查询 - 查询是线程化的。一旦线程获得了数据,它就会调用synchronized
方法WriteToDB
,该方法又接受一个名称 ( String field
) 并通过findByName
. 如果记录存在,则不执行任何其他操作来创建新记录。
现在我检查了方法确实只允许一次调用一个线程,这里是日志示例:
错误 2013-01-02 21:29:47,408 [Thread-21] 错误 - WriteToDB START
错误 2013-01-02 21:29:47,474 [Thread-21] 错误 - WriteToDB 已完成
错误 2013-01-02 21:29:47,475 [Thread-20] 错误 - WriteToDB START
错误 2013-01-02 21:29:47,571 [Thread-20] 错误 - WriteToDB 已完成
错误 2013-01-02 21:29:47,581 [Thread-49] 错误 - WriteToDB START
错误 2013-01-02 21:29:47,866 [Thread-49] 错误 - WriteToDB 已完成
错误 2013-01-02 21:29:47,867 [Thread-45] 错误 - WriteToDB START
错误 2013-01-02 21:29:48,202 [Thread-45] 错误 - WriteToDB 已完成
错误 2013-01-02 21:29:48,203 [Thread-48] 错误 - WriteToDB START
错误 2013-01-02 21:29:48,320 [Thread-48] 错误 - WriteToDB 已完成
但是,我得到重复的记录!!!每次我保存新记录时,我都会这样做flush:true
。我不明白为什么它一直在发生?我手动测试 - 在测试之前将一条已知记录添加到数据库中,并且它从未被复制,但是,正在保存的新记录最多被复制 6 次。
请帮忙。我需要索引一些东西吗?或者以特殊的方式冲洗一些东西?为什么会这样?
[2013 年 2 月 1 日更新]:
这是我用来保存记录的代码:
if(!f) { // Check if record doesn't exist then save, else nothing
f = new Feature(name: featureName)
if( !f.save(flush: true) ) {
f.errors.each {
log.error it
}
}
}
还有错误示例:
错误 2013-01-02 22:25:58,868 [Thread-20] 错误 util.JDBCExceptionReporter - 键“名称”的重复条目“自动传输”
错误 2013-01-02 22:25:58,873 [Thread-20] 错误 hibernate.AssertionFailure - 发生断言失败(这可能表明 Hibernate 中存在错误,但更有可能是由于会话使用不安全)消息:空 id在 Project2.Feature 条目中(发生异常后不要刷新 Session)
我可以这样解释(我在“保存”部分代码之前得到了 FindByName):我查找记录但它不存在所以我正在创建它,现在它抱怨重复条目,我得到变量“f”的空值后来我将其作为关系插入到另一个表中。
我想我可能会尝试使用 try catch 块修复此代码......想法?