繁体   English   中英

如何从事务中的Grails中的数据库错误中恢复

[英]How to recover from database errors in Grails within a transaction

简而言之,我正在尝试解决的问题是如何使用Hibernate从Grails应用程序中的某些数据库错误中恢复并继续事务跳过跳过作为一批更改一部分的失败行更新。

该应用程序使用Grails 2.3.11,但我也尝试使用1.3.8版本,但结果类似。

基本上,有一个Grails服务类,它对导入的记​​录列表进行迭代,并尝试适当地更新关联的主记录。 在某些情况下,在domain.save(flush:true)调用期间可能会发生异常,例如,由于诸如(数据截断:数据对于列...而言太长)之类的问题而引发org.hibernate.exception.DataException

在这一点上,我已经尝试:

  • 禁用交易
  • 对每个单独的记录使用domainObj.withTransaction()
  • 尝试各种@Transactional批注
  • 捕获异常后调用domain.clearErrors()domain.discard()
  • 尝试使用带有事务注释的嵌套服务以及noRollbackFor ,如下所示
  • 其他许多方法,但我尝试过的都没有奏效

示例代码:

@Transactional
class UpdateService {
    public updateBatch(Integer batchId) {
       ...
       list.each { record -> 
           record.value = 123
           try {
              nestedService.saveDomain()
           } catch (e) {
              record.clearErrors()
              record.discard()
           }
       }
       batch.status = "POSTED"
       batch.save()
   }
}

@Transactional
class NestedService {

   @Transactional(propagation = Propagation.REQUIRED, noRollbackFor = RuntimeException.class)
   public void saveDomain(domainObj) throws RuntimeException {
       if (domainObj.validate() && domainObj.save(flush:true) {
           log.info "domain $domain was saved"
       }
   }
}

一旦发生错误,我似乎无法清除休眠会话。 在每个后续记录被更新时,我收到错误:

org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction

它指示原始失败的域ID。


修订版:

瓦希德,谢谢你的建议。 我已经尝试过了。 我意识到一个问题是我正在跨事务边界传递对象。 因此,我对NestedService类进行了试验,其工作大致如下:

@Transactional(propagation = Propagation.REQUIRE_NEW)
public void saveDomain(domainObj) {
   def newObj = new Domain.get(domainObj.id)
   newObj.properties = domainObj.properties
   if (newObj.validate() && newObj.save(force:true) ) { ... }

我希望它能正常工作,但是即使我没有调用保存,原始的domainObj仍然会失败。 很奇怪...

一种简单的方法是循环然后使用validate()。 如果确实失败,则只需存储失败实体的ID并继续。

if(!domainObject.validate()){
    // store Id for trying it again later ?
}else{
    // Save
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM