繁体   English   中英

Grails或Spring方法级事务

[英]Grails or Spring Method Level Transaction

我是春季/春季交易的新手,阅读后仍然不清楚,所以我将其发布在这里,

我有一个注释为@Transactional的服务类,并且我有一些方法被注释为

@Transactional(propagation = Propagation.REQUIRES_NEW)

其中一些不是。

@Transactional
class SomeService {

    def findJob() {
        MyInstance myInstance = getMeAJob();
        if (myInstance) {
            doSomeThing(myInstance)
            doTask()
        }
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception)
    private doSomeThing(MyInstance myInst) {
        myObj = MyInstance.lock(myInst.id)
        try {
            differentObj = doTask(myObj)
            myObj.save()
            doAnotherThing()
            }
        } catch (Exception e) {

            log("Error in doAnotherTask")
        }
    }


    private doAnotherThing(MyInstace myInst) {
        perform some update on myInst
        myInstant.save(flush: true)
    }
    private doTask() {    
    }
  • 假设我有来自类级别的事务t1和来自doSomething()-REQUIRES_NEW的t2事务。
  • 将在t1中执行的方法-findJob()和doTask()
  • 将在t2中执行的方法doSomeThing()-在发生异常的情况下不会影响“ t1”(回滚)

    doAnotherThing()方法将使用哪种方法? 因为我从doSomething()调用它?

当您具有类作用域注释时,任何未注释的方法都将使用这些设置,并且带注释的方法将使用该注释中的设置覆盖类级别的设置。

但是请注意,在使用Spring的注释支持(使用@org.springframework.transaction.annotation.Transactional )时,仅支持公共方法。 不会有错误,但是注释会被忽略。

但是,即使将doSomeThing公开(通过隐式删除private关键字或显式地将其更改为public ),当您从findJob调用doSomeThing时,它也不会达到您的期望。 这是因为Spring的注释会在运行时触发类的代理的创建。 在这种情况下,为您的服务注册的Spring bean是一个代理实例,该代理实例具有您的类的“真实”实例作为其委托。 所有事务公共方法都被代理拦截,代理开始/加入/等。 交易,然后调用您的服务方法。 一旦在服务实例中的代理“之下”,所有方法调用都是直接的,并且任何注释设置均无效。 要使其正常工作,您需要在Spring bean上调用方法并通过代理来启动新事务。

为避免此代理问题,请改用Grails @grails.transaction.Transactional批注。 它支持与Spring注释相同的事务功能,但不是创建代理,而是AST转换重写您的方法以将它们包装在事务中。 这样就可以像执行操作一样进行直接方法调用,并创建新事务或在注释属性定义的其他事务语义下运行。

一段时间以前,我曾谈过在Grails中使用事务的问题,这可能会有所启发。

暂无
暂无

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

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