简体   繁体   中英

Spring + hibernate transaction timeout

I have an application which uses spring 4.0.1 + JPA + hibenate 4.2.8 (spring's JpaTransactionManager, LocalContainerEntityManagerFactoryBean with HibernateJpaDialect and apache's BasicDataSource as DataSource) for DB access. At a certain moment the application begins a long-running transation (native query select from a big table) which must be interrupted(rollbacked).

I tried several approaches to set timeout:

1) Set "javax.persistence.query.timeout" in JpaProperties of LocalContainerEntityManagerFactoryBean

2) setDefaultTimeout(...) of JpaTransactionManager

3) setHint("javax.persistence.query.timeout", 4000) of EntityManeger's Query.

4) setHint("org.hibernate.timeout", 4) of Hibernate's QueryImpl (hintName "org.hibernate.timeout")

But no one of these works. Is it possible to interrupt/rollback a transaction and how can i do this if it is?

My confs:

@Bean(name = "entityManagerFactory")
public EntityManagerFactory entityManagerFactory() {
    LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
    em.setDataSource(dataSource());
    em.setJpaDialect(new HibernateJpaDialect());
    em.setJpaVendorAdapter(jpaVendorAdapter());
    em.setJpaProperties(getJpaProperties());
    em.setPersistenceUnitName("persUnit");

    em.setMappingResources("/META-INF/app.hbm.xml");
    em.afterPropertiesSet();
    return em.getObject();
}

public Properties getJpaProperties() {
    Properties properties = new Properties();
        properties.put("hibernate.temp.use_jdbc_metadata_defaults", "false");
    properties.put("hibernate.cache.provider_configuration", 
"/ehcache.xml");
    properties.put("hibernate.cache.use_second_level_cache", "true");
    properties.put("hibernate.cache.use_query_cache", "true");
    properties.put("hibernate.generate_statistics", "true");
    properties.put("hibernate.jdbc.use_get_generated_keys", "true");
    properties.put("hibernate.jdbc.batch_size", "100");
    properties.put("hibernate.jdbc.fetch_size", "100");
    properties.put("hibernate.jdbc.batch_versioned_data", "true");
    properties.put("hibernate.cache.use_structured_entries", "true");
    properties.put("hibernate.cache.region.factory_class",    
    "org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory");

    return properties;
}

@Bean(name = "jpaVendorAdapter")
public JpaVendorAdapter jpaVendorAdapter() {
    HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
    jpaVendorAdapter.setDatabase(Database.ORACLE);
    jpaVendorAdapter.setDatabasePlatform("org.hibernate.dialect.Oracle10gDialect");
    return jpaVendorAdapter;
}

@Bean
public DataSource dataSource() {
    BasicDataSource dataSource = new BasicDataSource();
    dataSource.setUrl(getUrl());
    dataSource.setUsername(user);
    dataSource.setPassword(password);

    dataSource.setAccessToUnderlyingConnectionAllowed(true);

    dataSource.setDriverClassName(...);

    dataSource.setMaxWait(5000);
    dataSource.setMaxActive(30);
    dataSource.setMaxIdle(3);

    return dataSource;
}

Have you tried with a simple statement and setting a queryTimeout() first to your database server? May be your version Oracle does not support the hint: cstatement.setQueryTimeout(..), in which case did you try setting the Oracle server timeout setting?

There are also a few limitation on Oracle timeout, it does not guarantee the exact timeout as it seems: https://access.redhat.com/solutions/17829

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM