【问题标题】:spring Transaction management not working春季事务管理不起作用
【发布时间】:2015-02-20 07:55:11
【问题描述】:

我在春季使用程序化事务管理,现在我已切换到声明式事务管理。

会话工厂

<beans:bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <beans:property name="dataSource" ref="dataSource" />
        <beans:property name="packagesToScan" value="com.hcentive.cig.domain" />
        <beans:property name="hibernateProperties">
            <beans:props>
                <beans:prop key="hibernate.hbm2ddl.auto">update</beans:prop>
                <beans:prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect
                </beans:prop>
                <beans:prop key="hibernate.show_sql">true</beans:prop>
                <beans:prop key="hibernate.current_session_context_class">org.hibernate.context.internal.ThreadLocalSessionContext</beans:prop>
            </beans:props>
        </beans:property>
    </beans:bean> 

事务管理器

<beans:bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <beans:property name="sessionFactory">
            <beans:ref bean="sessionFactory" />
        </beans:property>
    </beans:bean>

现在如果运行我的代码

@Override
    @Transactional
    public Request saveRequest(Request request) {
        sessionFactory.getCurrentSession().save(request);
        return request;
    }

如果没有活动的事务,我得到异常保存无效

如果我删除下面的行

<beans:prop key="hibernate.current_session_context_class">org.hibernate.context.internal.ThreadLocalSessionContext</beans:prop>

我明白了

没有配置 CurrentSessionContext!

【问题讨论】:

标签: java spring hibernate configuration transactions


【解决方案1】:

你绝对不需要这个设置:

<beans:prop key="hibernate.current_session_context_class">org.hibernate.context.internal.ThreadLocalSessionContext</beans:prop>

Spring Transaction Management 层应该将 Hibernate Session 绑定到当前运行的 Thread。

设置很好,唯一可能导致它的原因来自您的以下声明:

不,它是从服务层调用的,我也尝试过 将@transactional 移动到服务层

你需要公开这个方法:

Request saveRequest(Request request);

通过服务接口,您可以将其注入任何其他组件(Web 或其他服务层 bean)。

要验证这一点,您可以在saveRequest 方法实现中放置一个调试断点,然后在调用堆栈中查找TransactionInterceptor。如果它不存在,那么 Spring 无法将您的方法调用包装到 Transaction Aspect 处理逻辑中。

【讨论】:

    【解决方案2】:

    将您的函数注释为 Transactional 并不一定足够。您还需要确保:

    • 您的 bean 是通过 Spring 创建的(定义为 @Component 并通过 componentScan 找到或在 xml 配置中声明)
    • 你的bean的引用需要通过Spring依赖注入获取

    【讨论】:

      【解决方案3】:

      要使@Transactional 有效,您必须告诉Spring 上下文您要使用它。没有针对该注释的处理器的注释是毫无用处的。要为 @Transactional 注释启用处理器,请将 &lt;tx:annotation-driven /&gt; 添加到您的上下文中。 (如参考指南中的here 所述)。

      在使用 Spring 时,您的休眠配置也存在问题,您不应该乱用 hibernate.current_session_context_class 配置属性(除非您使用某些特定的 JTA 提供程序,但显然您不是)。如果您开始设置该属性,您将破坏事务管理的正确弹簧集成。 Spring 已经为您设置了该属性,并且您的设置覆盖了默认值。

      您的配置应该如下所示。

      <beans:bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
          <beans:property name="dataSource" ref="dataSource" />
          <beans:property name="packagesToScan" value="com.hcentive.cig.domain" />
          <beans:property name="hibernateProperties">
              <beans:props>
                  <beans:prop key="hibernate.hbm2ddl.auto">update</beans:prop>
                  <beans:prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</beans:prop>
                  <beans:prop key="hibernate.show_sql">true</beans:prop>
              </beans:props>
          </beans:property>
      </beans:bean>   
      
      <beans:bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
              <beans:property name="sessionFactory" ref bean="sessionFactory" />
      </beans:bean>
      
      <tx:annotation-driven />
      

      【讨论】:

        猜你喜欢
        • 2014-02-19
        • 2011-12-17
        • 2020-11-10
        • 2017-08-11
        • 1970-01-01
        • 2011-04-22
        • 2015-04-18
        • 2014-08-10
        • 1970-01-01
        相关资源
        最近更新 更多