【问题标题】:Spring Transactional Management - Where to Place the Annotations?Spring 事务管理 - 在哪里放置注释?
【发布时间】:2011-03-22 00:12:49
【问题描述】:

如果我有一个事务管理类,其中我有两种方法,例如

void OuterMethod(Data somedata)
{
   this.InnerMethod(somedata)
}

@Transactional("mymanager")
void InnerMethod(Data somedata)
{
    //writes some things 
}

这是有效的吗?由于某种原因,我无法让它写入数据库,尽管它没有给我任何错误。

【问题讨论】:

  • 注意:按照约定,Java 中的方法名称以小写字符开头(即 outerMethod()、innerMethod())

标签: java spring transactions annotations


【解决方案1】:

Spring 不使用字节码 实现 AOP 的工具。所以 可以预见的是,如果一种方法 代理对象调用其他方法 在同一个对象中,方面将 不适用于方法调用。 然而,Spring 允许应用 通过设置此方法调用方面 将 ExposureProxy 设置为 True 并使用 AopContext.currentProxy().

信息可能有点过时,但据我所知,它仍然是准确的(虽然不确定“exposeProxy”标志)

http://forum.springsource.org/showthread.php?t=9926

【讨论】:

  • 抱歉 - 我对 Java 或 Spring 了解不多。你介意澄清一下吗?这是否意味着我应该只注释 OuterMethod?
  • 是的,这基本上就是它的精髓。问题是事务处理在不同的对象中。因此,您调用 proxy.OuterMethod() -> service.OuterMethod() -> service.InnerMethod(),您的所有事务处理都在 proxy.InnerMethod() 中,这无法从 service.OuterMethod() 访问 - 不是不使用AopContext.currentProxy() 这将是一个非常丑陋的解决方法。所以是的,注释 OuterMethod() 甚至两者都注释。
  • 没错。代理的替代方法是使用 AspectJ AOP,通过加载时编织(丑陋,必须替换类加载器)或编译时编织(使构建过程复杂,但 Eclipse 和 Maven 提供良好的工具支持)。
【解决方案2】:

这是一个棘手的话题。当 Spring 找到 @Transactional 注释时,它会为您的对象创建一个代理,使用基于 JDK 接口的代理或基于 CGLIB 子类的代理。在这两种情况下,代理都只适用于公共方法。我可能有点过于简单化了,但这是一般的想法。

因此,虽然仍然可以生成代理对象来处理带注释的 InnerMethod(),但它实际上不会被调用,因为非公共方法将“落入裂缝”。如果 Spring 警告你这点就好了,但事实并非如此。

简单的解决方案是确保您的注释在公共方法上。

【讨论】:

    猜你喜欢
    • 2015-01-07
    • 1970-01-01
    • 1970-01-01
    • 2019-01-09
    • 2012-12-14
    • 1970-01-01
    • 2023-02-16
    • 2019-11-02
    • 1970-01-01
    相关资源
    最近更新 更多