【问题标题】:TransactionProxyFactoryBean when switching from configuration-based Service beans to annotation based service beans从基于配置的服务 bean 切换到基于注释的服务 bean 时的 TransactionProxyFactoryBean
【发布时间】:2009-10-27 17:01:39
【问题描述】:

我读到了使用

  <context:component-scan base-package="tld.mydomain.business">
      <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
  </context:component-scan>

并用 @Service("myService") 注释我的服务 bean,我觉得很好,我会这样做,因为我已经用我的控制器这样做了。我通常的服务 bean 配置看起来像

  <bean id="userService" parent="txProxyTemplate">
    <property name="target">
      <bean class="tld.mydomain.business.UserServiceImpl"/>
    </property>
    <property name="proxyInterfaces" value="tld.mydomain.business.UserService"/>
  </bean>

既然我生成了它们,我如何将它们包装在诸如 TransactionProxyFactoryBean 之类的 Hibernate 代理中?还是有更好的方法来做到这一点?

我还没有完全使用@Repository,这是必需的吗?

干杯

尼克

【问题讨论】:

    标签: java hibernate spring proxy transactions


    【解决方案1】:

    在现代 Spring 应用程序中不鼓励使用 TransactionProxyFactoryBean,尽管它仍然有效。现在的典型方法是使用 @Transactional 注释类,然后将此元素粘贴到您的应用程序上下文文件中:

    <tx:annotation-driven transaction-manager="txManager"/>
    

    这个和其他策略在参考文档中有很深入的discussed,甚至还有一个关于TransactionProxyFactoryBean的旁注。

    【讨论】:

    • 非常感谢,我关注了一本关于 Spring 2 的书,其中推荐了 TransactionProxyFactoryBean,我现在看到我应该更仔细地查看文档。不过,只是快速跟进:这似乎仅适用于只有一个事务管理器的场景。不幸的是,我有两个,因为我需要使用两个不同的数据库。使用 TransactionProxyFactoryBean 没有问题。表 9.2 和 9.3 似乎并不表明我可以
    • 嗯,当我这样做时,访问我的服务时出现以下异常:org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'org.springframework.transaction.interceptor.TransactionInterceptor#0'必须是 [org.aopalliance.aop.Advice] 类型,但实际上是 [org.springframework.transaction.interceptor.TransactionInterceptor] 类型
    • 会不会是@Service("myService") 和@Transactional 注解冲突了?
    • 在这个 bug 上花费了数小时后,我决定将问题作为一个单独的问题发布,而不是在此线程中跟进。这是链接:stackoverflow.com/questions/1636063/…
    【解决方案2】:

    不需要

    &lt;context:include-filter type="annotation"expression="org.springframework.stereotype.Service"/&gt;

    一旦在基础包中找到@Service, @Repository, @Component...,Spring 就会注册。

    就像@Rob 所说,要么使用@Transactional&lt;aop:config&gt;...&lt;/aop:config&gt; 在服务级别处理您的交易。

    【讨论】:

    • 感谢您的提示,我已经删除了多余的杂物。您对我为什么会出现上面的 BeanNotOfRequiredTypeException 有什么建议吗?或者如何处理多个事务管理器?我从文档中看到,我可以使用 给出不同的建议,但在我看来,这仍然只存在于一个事务管理器中?
    • 通常BeanNotOfRequiredType 当您注入错误类型的 bean 但除非您发布堆栈跟踪,否则我无法进一步发言。那么你只需要1个PlatformTransactionManager,除非你有2个差异DataSource,否则不需要2个。
    【解决方案3】:

    如果您有两个不同的资源需要在同一个事务中,那么您将需要使用 JTA。请参阅我对先前问题here 的回答。您的配置需要如下所示:

    <tx:annotation-driven transaction-manager="txManager"/>
    
    <bean id="txManager" 
        class="org.springframework.transaction.jta.JtaTransactionManager">
        <property name="transactionManagerName" value="appserver/jndi/path" />
    </bean>
    

    appserver/jndi/path 需要替换为应用服务器附带的 JTA 事务管理器的 JNDI 路径(尽管您也可以使用独立的 JTA 事务管理器,例如 JOTM)。 2.5.x API 中提到的典型路径是:

    • “java:comp/UserTransaction”用于 Resin 2.x、Oracle OC4J (Orion)、JOnAS (JOTM)、BEA WebLogic
    • Resin 3.x 的“java:comp/TransactionManager”
    • GlassFish 的“java:appserver/TransactionManager”
    • “java:pm/TransactionManager”用于 Borland Enterprise Server 和 Sun Application Server(Sun ONE 7 及更高版本)
    • JBoss 应用服务器的“java:/TransactionManager”

    【讨论】:

    • 您好 Toolkit,非常感谢您的意见。当我使用 TransactionProxyFactoryBean 时,我已经能够绕过它,因为将它们保持在同一个事务中并不是绝对必要的,我也可以有两个,其中一个是只读的。这就是为什么我问说什么交易去哪里。将它们合二为一似乎是最好的主意。但两者都是 JDBC 连接,我没有使用过 JNDI。但是我会在早上阅读你的建议(现在这里是午夜)干杯-Nik
    猜你喜欢
    • 2017-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多