mysql上的Grails事务setSavePoint方法导致异常

Posted

技术标签:

【中文标题】mysql上的Grails事务setSavePoint方法导致异常【英文标题】:Grails transaction setSavePoint method on mysql causes exception 【发布时间】:2011-09-23 01:40:08 【问题描述】:

我在 mysql 5 中使用 grails。我在服务中使用 .withTransaction 进行事务管理。在 withTransaction 块中,我使用了导致以下异常的 savePoint() 方法。注意:我使用 setRollbackOnly() 方法没有任何问题。

2011-06-26 23:02:37,818 [quartzScheduler_Worker-7] ERROR listeners.ExceptionPrinterJobListener  - Exception occured in job: GRAILS_JOBS.com.exmp.bdg.PowerRollupJob
org.quartz.JobExecutionException: Transaction manager does not allow nested transactions [See nested exception: org.springframework.transaction.NestedTransactionNotSupportedException: Transaction manager does not allow nested transactions]
    at org.codehaus.groovy.grails.plugins.quartz.GrailsJobFactory$GrailsTaskClassJob.execute(GrailsJobFactory.java:81)
    at org.quartz.core.JobRunShell.run(JobRunShell.java:199)
    at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:546)
Caused by: org.springframework.transaction.NestedTransactionNotSupportedException: Transaction manager does not allow nested transactions
    at org.springframework.jdbc.datasource.JdbcTransactionObjectSupport.getConnectionHolderForSavepoint(JdbcTransactionObjectSupport.java:151)
    at org.springframework.jdbc.datasource.JdbcTransactionObjectSupport.createSavepoint(JdbcTransactionObjectSupport.java:104)
    at org.springframework.transaction.support.AbstractTransactionStatus.createSavepoint(AbstractTransactionStatus.java:176)
    at org.springframework.transaction.SavepointManager$createSavepoint.call(Unknown Source)
    at com.exmp.bdg.service.PowerRollupService$_doRollup_closure2.doCall(PowerRollupService.groovy:85)

【问题讨论】:

Mysql 不支持保存点。但是如果你可以使用 Postresql 的话。 【参考方案1】:

默认情况下,hibernate 和 MySQL 的事务管理器没有启用保存点。

在 BootStrap.groovy 中添加以下内容:

transactionManager.setNestedTransactionAllowed(true)

然后在一个事务中你可以执行以下操作:

Thing.withTransaction  status ->
  //Do some work and a save
  def savePoint = status.createSavepoint()
  //do other work
  if(checkOk)
  
    //Everything worked so don't need the save point anymore
    status.releaseSavepoint(savePoint)
  
  else
  
    //The other work did not work so rollback from it.
    status.rollbackToSavepoint(savePoint)
  


【讨论】:

为什么不会这样做? 它的非默认行为。 不不,我的意思是:他们选择这个默认值有什么原因吗?启用嵌套事务有什么危险吗? 我能说的最好的是它是后来添加的,并且只适用于现代 MySQL,这几乎是现在的默认设置。

以上是关于mysql上的Grails事务setSavePoint方法导致异常的主要内容,如果未能解决你的问题,请参考以下文章

Grails 2.3 IntegrationSpec 不能是事务性错误

Grails下如何防止异常导致事务回滚?

以编程方式处理 Grails 事务

Grails:未刷新的会话和回滚的事务有啥区别?

如何使事务在 Grails 中工作

grails:在服务上玩事务(回滚)