2013-12-10 32 views
0

我在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; 
    } 
} 
+0

發佈您的彈簧配置和休眠配置。 –

+0

只是想知道爲什麼這是一個問題,您正在使用hibernate,因此直到調用flush或在事務結束時纔會發出查詢。 –

+0

Hibernate刷新f.e.在執行查詢之前。這是故意的,應該在autocommit關閉時正常工作。 –

回答

0

Spring自動爲您管理連接(假設你使用Spring控制事務和數據源從彈簧配置)。所以你不需要搞亂連接的只讀設置。

另外,如果您使用彈簧將數據源注入休眠,則hibernate.connection.*屬性無用。

+0

我將配置添加到了我原來的帖子中。 –

+0

如前所述,hibernate.connection。*屬性是無用的。嘗試將數據源添加到事務管理器。 –

+0

我測試過,沒有任何改變。自動提交仍處於活動狀態。我添加了hibernate.connection屬性僅用於測試目的。 –