Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Hibernate和JDBC在一个事务中_Java_Hibernate_Spring_Jdbc_Transactions - Fatal编程技术网

Java Hibernate和JDBC在一个事务中

Java Hibernate和JDBC在一个事务中,java,hibernate,spring,jdbc,transactions,Java,Hibernate,Spring,Jdbc,Transactions,我有一个方法,标记为@Transactional。 它由几个函数组成,其中一个使用JDBC,第二个使用Hibernate,第三个使用JDBC。 问题是Hibernate函数所做的更改在最后一个使用JDBC的函数中不可见 @Transactional void update() { jdbcUpdate1(); hibernateupdate1(); jdbcUpdate2(); // results of hibernateupdate1() are not visible here

我有一个方法,标记为@Transactional。 它由几个函数组成,其中一个使用JDBC,第二个使用Hibernate,第三个使用JDBC。 问题是Hibernate函数所做的更改在最后一个使用JDBC的函数中不可见

@Transactional
void update() {
  jdbcUpdate1();
  hibernateupdate1();
  jdbcUpdate2(); // results of hibernateupdate1() are not visible here    
}
所有函数都配置为使用相同的数据源:

<bean id="myDataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
        <property name="targetDataSource" ref="targetDataSource"/>
    </bean>

    <bean id="targetDataSource" class="org.apache.commons.dbcp.BasicDataSource"
          destroy-method="close" lazy-init="true" scope="singleton">
       <!-- settings here -->
    </bean>
在hibernate函数中使用。
谢谢。

首先,在使用hibernate时避免使用JDBC


然后,如果你真的需要它,使用它。如果您的hibernate版本还没有此方法,请从
session.Connection()

获取
连接。如果使用正确的Spring设置,您可以在同一事务中使用JDBC和hibernate:

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
</bean>

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

<bean id="myDao" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager" ref="transactionManager"/>
    <property name="target">
        <bean class="MyDaoImpl">
            <property name="dataSource" ref="dataSource"/>
            <property name="sessionFactory" ref="sessionFactory"/>
        </bean>
    </property>
    <property name="transactionAttributes">
        <props>
            <prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop>
            <prop key="*">PROPAGATION_REQUIRED</prop>
        </props>
    </property>
</bean>

传播支持,只读
需要进行传播
这假设DAO的JDBC部分使用JdbcTemplate。如果没有,您有几个选择:

  • 使用DataSourceUtils.getConnection(javax.sql.DataSource)获取连接
  • 用TransactionWareDatasourceProxy包装传递给DAO的数据源(但不一定是传递给SessionFactory的数据源)
后者是首选,因为它将DataSourceUtils.getConnection隐藏在代理数据源中


这当然是XML路径,将其转换为基于注释的路径应该很容易。

问题是,Hibernate引擎上的操作不会导致立即执行SQL。您可以在Hibernate会话上通过调用
flush
手动触发它。然后,在hibernate中所做的更改将对同一事务中的SQL代码可见。只要您执行
DataSourceUtils.getConnection
来获取SQL连接,因为只有这样您才能让它们在同一事务中运行


在相反的方向,这是更棘手的,因为您有1级缓存(会话缓存),也可能有2级缓存。对于二级缓存,如果缓存了行,则对数据库所做的所有更改对Hibernate都将不可见,直到缓存过期

对于那些从谷歌来到这里的人,我的解决方案。我在hibernate flush函数的末尾添加了session.flush()。之后,它的写入结果将在下一个jdbc读取函数(在同一事务中)中可用。
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
</bean>

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

<bean id="myDao" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager" ref="transactionManager"/>
    <property name="target">
        <bean class="MyDaoImpl">
            <property name="dataSource" ref="dataSource"/>
            <property name="sessionFactory" ref="sessionFactory"/>
        </bean>
    </property>
    <property name="transactionAttributes">
        <props>
            <prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop>
            <prop key="*">PROPAGATION_REQUIRED</prop>
        </props>
    </property>
</bean>