Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
grails withTransaction-为什么它位于域对象上?_Grails_Rollback - Fatal编程技术网

grails withTransaction-为什么它位于域对象上?

grails withTransaction-为什么它位于域对象上?,grails,rollback,Grails,Rollback,我们需要能够回滚服务中的复杂事务,而不向调用方抛出异常。我的理解是,实现这一点的唯一方法是使用withTransaction 问题是: 为什么我必须对域对象(如Books.withTransaction)调用此函数 如果没有相关的域对象,那么随机选择一个域对象的结果是什么 下面或多或少是我想做的。该用例用于从帐户中提款并将其存入信用卡。如果传输失败,我们希望回滚事务,但不回滚支付记录日志,它必须在单独的事务中提交(使用RequiresNew)。在任何情况下,服务方法都必须返回复杂对象,而不是异常

我们需要能够回滚服务中的复杂事务,而不向调用方抛出异常。我的理解是,实现这一点的唯一方法是使用withTransaction

问题是:

  • 为什么我必须对域对象(如Books.withTransaction)调用此函数
  • 如果没有相关的域对象,那么随机选择一个域对象的结果是什么
  • 下面或多或少是我想做的。该用例用于从帐户中提款并将其存入信用卡。如果传输失败,我们希望回滚事务,但不回滚支付记录日志,它必须在单独的事务中提交(使用RequiresNew)。在任何情况下,服务方法都必须返回复杂对象,而不是异常

    好的

    Class SomeService {
        @NotTransactional
        SomeComplexObject someMethod() {
            SomeDomainObject.withTransaction{ status ->
                DomainObject ob1 = new DomainObject.save()
                LogDomainObject ob2 = insertAndCommitLogInNewTransaction()
                SomeComplexObject ob3 = someAction()
                if (!ob3.worked) {
                     status.setRollbackOnly() // only rollback ob1, not ob2!
                }
                return ob3
            }
        }
    }
    

    以上是有缺陷的-我假设“returnob3”不会从方法返回ob3,因为它在闭包中。不知道如何从闭包内部到外部进行通信。

    对于您的主要问题:如果您愿意,可以选择一个随机域对象,它不会造成任何伤害。或者,如果愿意,您可以找到当前会话并在该会话上打开一个事务:

    grailsApplication.sessionFactory.currentSession.withTransaction { /* Do the things */ }
    
    从风格上来说,我不喜欢这里。其他人可能会

    不知道如何从闭包内部到外部进行通信

    一般来说,这可能很困难
    withTransaction
    原则上可以返回它想要的任何东西,不管它的闭包参数返回什么。但事实证明,
    withTransaction
    返回其闭包返回的值。看这里:

    groovy> println(MyDomainObject.withTransaction { 2 + 2 })
    4
    

    按照惯例,所有采用闭包的
    withFoo
    方法都应该以这种方式工作,这样您就可以做您正试图做的事情。

    我假设这个问题来自grails 2应用程序,2015年的这个问题在此之前已经解决

    我在任何Grails2文档中都找不到这一点,但是服务在其方法中注入了一个神奇的
    transactionStatus
    变量。(至少在grails 2.3.11中)

    您只需关闭所有注释,然后使用注入的变量即可

    Class SomeService {
        SomeComplexObject someMethod() {
            DomainObject ob1 = new DomainObject.save()
            LogDomainObject ob2 = insertAndCommitLogInNewTransaction()
            SomeComplexObject ob3 = someAction()
            if (!ob3.worked) {
                 transactionStatus.setRollbackOnly() // transactionStatus is magically injected.
            }
            return ob3
        }
    } 
    
    这个特性在Grails2中,但没有文档记录。它在Grails3中有记录。


    搜索
    transactionStatus

    为什么不在方法中添加
    @Transactional
    注释?@christopher,我相信在使用“withTransaction”创建的事务之外创建一个事务除了降低性能(略微降低)之外没有其他用途。我们知道我们必须使用WithTransaction才能回滚而不抛出异常。我的意思是代替!我懂了。
    withTransaction
    方法有特定的使用范围,是的,这就是其中之一。很好!有一个问题,您是如何运行groovy控制台的,它使用事务和域对象的东西来获取grails的?为了测试这些特性,我通常会在Intellij中创建一个新的grails项目,这需要一些时间。@JohnLittle
    GrailsShell
    GrailsConsole