我在Tomcat 6上使用Hibernate 3.3.2和Spring 3.2.3。我想使用連接池並決定測試Oracle的UCP(用於Oracle 11.2.0.4)。在Tomcat上禁用autoCommit for Oracle UCP 6
(我添加編輯這篇文章的結尾,因爲情況後幾個發展變化)
我不能擺脫,雖然自動提交的。我嘗試在Tomcat的context.xml中像這樣配置數據源:
<Resource
name="jdbc/datasource"
auth="Container"
type="oracle.ucp.jdbc.PoolDataSource"
[snip]
initialPoolSize="3"
minPoolSize="3"
maxPoolSize="10"
factory="oracle.ucp.jdbc.PoolDataSourceImpl"
connectionFactoryClassName="oracle.jdbc.pool.OracleDataSource"
connectionProperties=";AutoCommit=false;"
/>
注意分號。我加了他們,因爲this post。但它不起作用,既不用分號也不用。
在我的申請,我有一些測試代碼是這樣的:
PoolDataSourceImpl pds;
try {
pds = (PoolDataSourceImpl) hc.dataSource();
System.out.println("Print all conn props:" + pds.getConnectionProperties().toString());
} catch (NamingException e) {
e.printStackTrace();
}
sessionFactory.getCurrentSession().doWork(new Work() {
@Override
public void execute(Connection connection) throws SQLException {
System.err.println("################################### autocommit is " + connection.getAutoCommit());
}
});
輸出是:
Print all conn props:{AutoCommit=false}
################################### autocommit is true
我也試過在Hibernate中禁用自動提交與hibernate.connection.autocommit = FALSE ,但那也行不通。
編輯:我的配置如下:
@Configuration
public class HibernateConfig {
@Bean
LocalSessionFactoryBean hibernateSessionFactory() throws Exception {
LocalSessionFactoryBean factory = new LocalSessionFactoryBean();
factory.setMappingResources(new String[] { "mapping.hbm.xml" });
factory.setHibernateProperties(hibernateProperties());
factory.setDataSource(dataSource());
return factory;
}
@Bean
public DataSource dataSource() throws NamingException {
return (DataSource) new InitialContext().lookup("jdbc/datasource");
}
@Bean
public HibernateTransactionManager transactionManager() throws Exception {
HibernateTransactionManager manager = new HibernateTransactionManager();
manager.setSessionFactory(hibernateSessionFactory().getObject());
return manager;
}
@Bean
Properties hibernateProperties() throws IOException {
PropertiesFactoryBean bean = new PropertiesFactoryBean();
bean.setLocation(new ClassPathResource("hibernate.properties"));
bean.afterPropertiesSet();
return bean.getObject();
}
和
@Configuration
@EnableTransactionManagement
@EnableScheduling
@Import({ HibernateConfig.class, ... })
@ComponentScan(basePackages = ...)
public class ServerCommonsConfig {
[...]
}
和
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@Import({ ServerCommonsConfig.class, ... })
public class ApplicationServerConfig {
[...]
}
hibernate.properties看起來是這樣的:
# Hibernate Properties
#hibernate.bytecode.provider=cglib
hibernate.dialect=org.hibernate.dialect.Oracle10gDialect
hibernate.show_sql=true
hibernate.format_sql=true
hibernate.cache.provider_class=org.hibernate.cache.NoCacheProvider
hibernate.cache.use_second_level_cache=false
hibernate.cache.use_query_cache=false
hibernate.jdbc.batch_size=200
hibernate.connection.autocommit=false
connection.autocommit=false
編輯2:
顯然有一個錯誤與autoCommit屬性的名稱。它必須是
connectionProperties=";autoCommit=false;"
在開始處有一個小「a」。我使用了大寫版本,因爲我發現在one of the only examples of configuring UCP with autoCommit off on the net。
現在測試輸出是
Print all conn props:{autoCommit=false}
false
################################### autocommit ist false
這是所有罰款和花花公子,但現在沒有被提交。我看到Hibernate的寫作DELETE語句,當我刷新和@Transactional方法結束後,我可以調試到Spring的TransactionAspectSupport和HibernateTransactionManager.doCommit(),最後JDBCTransaction.commitAndResetAutoCommit(),它說
private void commitAndResetAutoCommit() throws SQLException {
try {
jdbcContext.connection().commit();
}
finally {
toggleAutoCommit();
}
}
,但數據庫仍然沒有被這個。沒有更改提交。
數據訪問代碼示例(這是服務器上的服務客戶端通過Spring HTTP調用程序調用):
@Transactional
@Component
public class ServiceImpl implements Service {
@Resource
private SessionFactory sessionFactory;
//added this method to test the autocommit issue
@Override
public List<Stuff> getStuff(Long id) {
Query query = sessionFactory.getCurrentSession().createQuery(
"FROM Stuff p");
@SuppressWarnings("unchecked")
List<Stuff> list = query.list();
for (Stuff stuff : list) {
sessionFactory.getCurrentSession().delete(stuff);
}
//this flush used to commit the changes
//instead, now nothing gets committed
sessionFactory.getCurrentSession().flush();
return null;
}
}
發佈您的彈簧配置和休眠配置。 –
只是想知道爲什麼這是一個問題,您正在使用hibernate,因此直到調用flush或在事務結束時纔會發出查詢。 –
Hibernate刷新f.e.在執行查詢之前。這是故意的,應該在autocommit關閉時正常工作。 –