spring事务管理不起作用

时间:2015-02-20 07:55:11

标签: java spring hibernate configuration transactions

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

SessionFactory

<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> 

TransactionManager

<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!

3 个答案:

答案 0 :(得分: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无法将您的方法调用包装到事务方面处理逻辑中。

答案 1 :(得分:1)

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

使用Spring时你的hibernate配置也有问题你不应该使用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 />

答案 2 :(得分:0)

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

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