当前位置: 首页 > 知识库问答 >
问题:

Grails或Spring方法级事务

祁刚毅
2023-03-14

我是Spring/圣杯交易的新手,阅读后我仍然不清楚,所以我在这里发布,

我有一个服务类,它被注释为@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() {    
    }

> < li >假设,我有来自类级别的事务t1和来自doSomething()- REQUIRES_NEW的事务t2。 < li >将在t1 - findJob()和doTask()中执行的方法 < li>

将在t2中执行的方法- doSomeThing() -在异常(回滚)情况下不影响“t1”

哪一个将用于doOtherThing()方法?因为我是从doSomething()调用它的?

共有1个答案

杨甫
2023-03-14

当您具有类范围的批注时,任何未批注的方法都将使用这些设置,带批注的方法将使用该批注中的设置覆盖类级设置。

但是,请注意,当使用Spring的注释支持时(使用<code>@org.springframework.transaction.annotation.Transactional</code>),只支持公共方法。不会出现错误,但注释会被默认忽略。

但是,即使您将doSomeThing设置为public(或者通过删除< code>private关键字隐式设置,或者通过将其更改为< code>public)当您从< code>findJob中调用< code>doSomeThing时,它也不会执行您预期的操作。这是因为Spring的注释在运行时触发了类的代理的创建。在这种情况下,为您的服务注册的Spring bean是一个代理实例,它将您的类的“真实”实例作为其委托。所有事务性的公共方法都被代理截获,代理启动/加入/等等。然后调用您的服务方法。一旦您在服务实例中的代理之下,所有的方法调用都是直接的,任何注释设置都不起作用。要让它工作,您需要调用Spring bean上的方法,并通过代理启动一个新的事务。

要避免此代理问题,请使用Grails<code>@Grails.transaction。而使用事务性注释。它支持与Spring注释相同的事务特性,但AST转换将重写您的方法以将它们封装在事务中,而不是创建代理。这使得可以像您正在做的那样进行直接方法调用,并创建新的事务或在注释属性定义的其他事务语义下运行。

不久前,我做了一次关于在Grails中使用事务的讨论,这可能会有所启发。

 类似资料:
  • 试图收集和理解@事务性注释的要点并越过了一点。因此,在使用事务性注释时,我们需要记住的主要事情是: 事务注释只能应用于公共方法[根据Spring@Transactional属性对私有方法起作用吗? 事务性注释应该应用于具体的类,而不是接口[根据我应该将@transactional annotation放在接口定义还是实现类的位置? 事务注释应应用于服务级别[根据Spring@Transaction

  • Spring Transaction Propagation如何为Propagation_REQUIRED和Propagation_REQUIRED_NEW工作? 请提供有关类到类级别和方法到方法级别的传播的信息。 我还需要知道如何初始化/启动这些事务,并在当前事务完成时恢复以前的事务,以进行传播。 在需要传播和需要新传播的情况下使用单个事务时,事务将如何决定何时需要提交/回滚?

  • 我使用的是grails 1.3.7,代码如下: Grails服务: 我的例外: } 当代码抛出MyException时,我发现以下错误:事务回滚,因为它已被标记为仅回滚 注:如果我更改static transactional=true,则不会发生错误。 知道吗?

  • 我正在从事一个项目,我们需要向用户提供现场级访问。 示例: 假设有一个名为employee的实体,其中包含多个字段 应用程序应该允许在实体的字段级别进行安全访问。 用户被允许根据访问来编辑/读取字段。 我们已经想到了使用Spring acl的实现,但它提供了实例级安全性。 有人能告诉我一个优雅的方法来实现它吗? 提前谢谢。

  • 问题内容: 事务成功或回滚后,我需要调用某些方法。我正在使用 该应用程序使用一些外部Web服务,这些内部Web服务在回滚内部事务时需要“清除”。有没有办法在不使用声明式事务管理的情况下完成此操作。 问题答案: 在Hibernate中,您可以扩展和覆盖 方法并将其注册在 或中。 在Spring中,您可以使用扩展,覆盖和注册 。 编辑 使用Spring Aop向所有带注释的方法添加同步的示例

  • 我是Grails和Goovy的新手。我在这里查看了Grails框架文档以及关于乐观与悲观锁定的讨论 从文档中可以清楚地看出: > Grails默认使用乐观锁定。 可以关闭乐观锁定(通过使用version=false) 如果您关闭了乐观锁定,并担心并发更新时丢失数据,则必须启用悲观锁定(通过使用lock()方法) 我的问题: > < li> 似乎有3种模式。两个显式命名:乐观和悲观,另一个是隐式的—