Spring和Hibernate:多个连接,线程安全

时间:2014-10-07 16:05:54

标签: java sql spring hibernate thread-safety

我有一个现有的项目工作正常,但现在我必须实现一个备份系统,该系统在每天执行并将数据库转储到文件。我想用ScheduledTask来解决这个问题,但这意味着还有另一个Thread使用Hibernate。

我的问题:我如何才能确保Hibernate Thread的安全?

我有以下代码 - (片段):

在applicationContext.xml

<bean id="myEmf"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dbDataSource" />
    <property name="packagesToScan" value="redb.main.core.model" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
    </property>
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.hbm2ddl.auto">validate</prop>
            <prop key="hibernate.dialect">org.hibernate.dialect.SQLServer2008Dialect</prop>
            <!-- <prop key="hibernate.enable_lazy_load_no_trans">true</prop> -->
        </props>
    </property>
</bean>

<!-- Transaction Management -->
<tx:annotation-driven transaction-manager="txManager" />
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="myEmf" />
</bean>

<bean id="persistenceExceptionTranslationPostProcessor"
    class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

所以我可以通过

获得EntityManager
@PersistenceContext
protected EntityManager entityManager;

但如果我理解正确,那么每个Thread都需要EntityManager中自己的EntityManagerFactory

如何在其他课程中创建新的EntityManager

我没有persistence.xml。我必须创建吗?

1 个答案:

答案 0 :(得分:0)

他 - 他。欢迎来到地狱。

主要问题是,Spring试图用基于方面的解决方案来做到这一点。虽然这是错误的(或不可取的),但在琐碎的情况下它可以工作。

您的问题的一般答案是,EntityManagerFactory 可以是您软件中的全局静态对象,但如果我只是使用它,我会被扔石头。

默认情况下,spring aop在部署时“编织”您的应用程序,通过其注释查找所有数据库实体类,并包装其方法以始终提供现有的实体管理器。这就是理论。但这不是惯例。

实践是你几乎无法控制将要发生的事情。

我做了什么:有一个名为org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter的servlet过滤器,它可以为每个请求打开一个实体管理器,并根据需要刷新/关闭它。是的,它的名字是关于“视图”的,但很快它的名字就是它的第一个错误:实际上我们不得不把它称为“requesttransactionfilter”等等。它与MVC视图没有任何关系,它正在处理来自servlet容器的http请求实体。

如果你不喜欢在spring应用程序中使用servlet过滤器,那么还有一个名为OpenEntityManagerInViewInterceptor的弹簧拦截器,其功能也非常相似。

以编程方式,您可以通过EntityManager方法从EntityManagerFactory生成createEntityManager()

快乐的谷歌搜索!你已经走了很长的路。