2013-12-10 33 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属性仅用于测试目的。 –