[英]Hibernate and JDBC in one transaction
我有一個方法,標記為@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>
myDataSource bean用於代碼中。 myDataSource.getConnection()用於處理jdbc函數和中的連接
getHibernateTemplate().execute(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException, SQLException {
...
}
});
用於休眠函數。 謝謝。
首先,避免在使用hibernate時使用JDBC。
然后,如果您真的需要它,請使用Session.doWork(..)
。 如果你的hibernate版本還沒有這個方法,請從session.connection()
獲取Connection
。
問題是,Hibernate引擎上的操作不會導致立即執行SQL。 你可以在Hibernate會話上手動調用flush
來觸發它。 然后,在同一事務中的SQL代碼中可以看到hibernate中所做的更改。 只要你做DataSourceUtils.getConnection
來獲得SQL連接,因為只有這樣你才能讓他們在同一個事務中運行...
在相反的方向上,這更棘手,因為你有一級緩存(會話緩存),也可能是二級緩存。 對於二級緩存,如果緩存行,則對Hibernate所做的所有更改都將對Hibernate不可見,直到緩存過期。
如果使用正確的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。
這當然是XML路徑,應該很容易將其轉換為基於注釋。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.