我有一个每隔几分钟就会运行一次的工作,一个新的域对象被实例化并填充来自 api 调用的数据,然后调用 .save() 以提交到数据库。
此应用程序使用 GORM Mongo 插件。
在将新的战争部署到测试箱后, org.grails.datastore.mapping.core.OptimisticLockingException
每次作业开始时我都会收到并尝试处理文件,进行 api 调用,然后保存结果。日志 (&error) 指向 .save() 调用。
日志显示“正在解析文件内容”后引发错误
log.debug "Parsing file contents"
def map = [:]
def contents = new CsvParser().parse(fileContents, separator: '\t')
//Make a map of CSV contents
contents.each{ line ->
map[line["name"]] = [:]
line.columns.each{
map[line["name"]][it.key[0].toLowerCase()+it.key.substring(1)]=line[it.key]
}
def thing = apiService.findThingDetailsByThingId(line["Thing_ID"].replaceAll( "[^\\d]", "" ))
thing.save()
map[line["name"]].putAll(thing.toMap())
}
下面的堆栈跟踪可能是矫枉过正。
Heuristic completion: outcome state is rolled back; nested exception is org.springframework.transaction.TransactionSystemException: Could not commit Datastore transaction; nested exception is org.grails.datastore.mapping.core.OptimisticLockingException: The instance was updated by another user while you were editing
org.springframework.transaction.HeuristicCompletionException: Heuristic completion: outcome state is rolled back; nested exception is org.springframework.transaction.TransactionSystemException: Could not commit Datastore transaction; nested exception is org.grails.datastore.mapping.core.OptimisticLockingException: The instance was updated by another user while you were editing
at org.grails.datastore.gorm.GormStaticApi.withNewSession(GormStaticApi.groovy:756)
at grails.plugins.quartz.GrailsJobFactory$GrailsJob.execute(GrailsJobFactory.java:102)
at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
Caused by: org.springframework.transaction.TransactionSystemException: Could not commit Datastore transaction; nested exception is org.grails.datastore.mapping.core.OptimisticLockingException: The instance was updated by another user while you were editing
at org.grails.datastore.mapping.transactions.DatastoreTransactionManager.doCommit(DatastoreTransactionManager.java:156)
... 8 more
Caused by: org.grails.datastore.mapping.core.OptimisticLockingException: The instance was updated by another user while you were editing
at org.grails.datastore.mapping.mongo.engine.MongoEntityPersister$5.doInDB(MongoEntityPersister.java:664)
at org.grails.datastore.mapping.mongo.engine.MongoEntityPersister.updateEntry(MongoEntityPersister.java:625)
at org.grails.datastore.mapping.mongo.engine.MongoEntityPersister.updateEntry(MongoEntityPersister.java:82)
at org.grails.datastore.mapping.engine.NativeEntryEntityPersister$2.run(NativeEntryEntityPersister.java:862)
at org.grails.datastore.mapping.core.impl.PendingOperationExecution.executePendingOperation(PendingOperationExecution.java:33)
at org.grails.datastore.mapping.core.AbstractSession.flushPendingOperations(AbstractSession.java:364)
at org.grails.datastore.mapping.core.AbstractSession.flushPendingUpdates(AbstractSession.java:343)
at org.grails.datastore.mapping.core.AbstractSession.flush(AbstractSession.java:263)
at org.grails.datastore.mapping.mongo.MongoSession.flush(MongoSession.java:126)
at org.grails.datastore.mapping.transactions.DatastoreTransactionManager.doCommit(DatastoreTransactionManager.java:151)
... 8 more
org.springframework.transaction.HeuristicCompletionException: Heuristic completion: outcome state is mixed; nested exception is org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
at org.grails.datastore.gorm.GormStaticApi.withNewSession(GormStaticApi.groovy:756)
at grails.plugins.quartz.GrailsJobFactory$GrailsJob.execute(GrailsJobFactory.java:102)
at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
Caused by: org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
... 6 more
在尝试重新启动 tomcat、检查 mongo 连接等之后,我通过删除域对象 mongo 集合来解决此问题(我最近对域对象进行了一系列更改)。这个错误是否可能是由域对象的更改和 mongo/GORM 数据模型冲突引起的?如果是这样,我怎样才能避免将来需要删除集合?
我不相信其他东西可能正在访问同一个域集合,所以不要认为这是一个乐观的锁定异常,但如果是的话,我可以在 mongo 端运行哪些命令来查看哪些连接正在访问该集合?