java - Spring 和 Hibernate 的事务管理使非 Activity 事务成为可能

标签 java spring oracle hibernate transactions

我正在使用 Spring 和 Hibernate 管理一个 Java Web 应用程序。 我使用 Spring 和 Hibernate 工具来处理持久性级别,因此我不需要提交\回滚我的事务。 该应用程序是并发的,因此用户可以修改相同的记录,我决定使用 Read Committed 作为隔离级别。

问题是有时我会在日志中发现 JDBC 错误,并且所有下一个请求都会出现相同的错误,从而阻止应用程序行为。

这些是事务管理中涉及的组件:

@Bean
    public SpringLocalSessionFactoryBean sessionFactory(DataSource dataSource){
        SpringLocalSessionFactoryBean bean = new SpringLocalSessionFactoryBean();
        bean.setConfigLocation(new ClassPathResource("hibernate.cfg.xml"));
        bean.setDataSource(dataSource);
        return bean;
    }

    @Bean
    public HibernateTransactionManager transactionManager(SessionFactory sessionFactory){
        HibernateTransactionManager tm = new HibernateTransactionManager();
        tm.setSessionFactory(sessionFactory);
        return tm;
    }

在数据库 session 监视器中,当发生这种情况时,我得到了一个 INACTIVE 事务。

我得到的错误如下:

WARN  - (SqlExceptionHelper.java:144) - SQL Error: 0, SQLState: null
14/03/2016 15:46:06 - ERROR - (SqlExceptionHelper.java:146) - Connection oracle.jdbc.driver.T4CConnection@1a6d7ad6 is closed.
14/03/2016 15:46:06 - ERROR - (AutoCompleterController.java:73) - could not prepare statement
org.hibernate.exception.GenericJDBCException: could not prepare statement
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:196)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:160)
    at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1885)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1862)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1839)
    at org.hibernate.loader.Loader.doQuery(Loader.java:910)
Caused by: java.sql.SQLException: Connection oracle.jdbc.driver.T4CConnection@1a6d7ad6 is closed.
    at org.apache.tomcat.dbcp.dbcp.DelegatingConnection.checkOpen(DelegatingConnection.java:398)
    at org.apache.tomcat.dbcp.dbcp.DelegatingConnection.prepareStatement(DelegatingConnection.java:279)
    at org.apache.tomcat.dbcp.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.prepareStatement(PoolingDataSource.java:313)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:162)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:186)
    ... 97 more

问题是事务和连接应该自动打开和关闭......我希望并发修改失败的事务能够回滚......但它们似乎变得不活跃。

我附加了我的 hibernate 配置。

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>

<!--        <property name="hibernate.hbm2ddl.auto">update</property> -->
        <property name="hibernate.connection.isolation">2</property>

        <!-- Disable the second-level cache -->
        <property name="hibernate.cache.use_second_level_cache">false</property>
        <property name="hibernate.id.new_generator_mappings">true</property>
        <property name="hibernate.connection.autocommit">false</property>

        <!-- Show and print nice SQL on stdout -->
        <property name="hibernate.show_sql">false</property>
        <property name="hibernate.format_sql">false</property>
        <property name="hibernate.use_sql_comments">false</property>
        <property name="hibernate.generate_statistics">false</property>

    </session-factory>
</hibernate-configuration>

作为连接库,我使用 ojdbc。 任何帮助将不胜感激。我不知道去哪里检查了。

PS:我补充说这个错误每 2 天出现一次。

编辑:只是另一个集成,这是我在我的 server.xml 上的内容,它可能与这里的某些内容相关吗?

  <Resource name="jdbc/ToolSfDB" global="jdbc/ToolSfDB" auth="Container" type="javax.sql.DataSource"
      driverClassName="oracle.jdbc.OracleDriver"
      url="jdbc:oracle:thin:@//oracle01-internal.local:1521/orcl01"
      username="tools"
      password="mypwd"
      maxActive="10"
      maxIdle="2"
      minIdle="1"
      suspectTimeout="60"
      timeBetweenEvictionRunsMillis="30000"
      minEvictableIdleTimeMillis="60000"
      validationQuery="select 1 from dual"
      validationInterval="30000"
      testOnBorrow="true"
      removeAbandoned="true"
      removeAbandonedTimeout="60"
      abandonWhenPercentageFull="10"
      maxWait="10000"
      maxAge="60000"/>

最佳答案

看来是因为无法打开与oracle的连接导致交易出现问题。如果您正在使用 oracle 10g,因为您在 hibernate.cfg.xml

中进行了配置
    <session-factory>
      <property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>

和 您正在使用 oracle thin driver:

 <Resource name="jdbc/ToolSfDB" global="jdbc/ToolSfDB" auth="Container" type="javax.sql.DataSource"
      driverClassName="oracle.jdbc.OracleDriver"
      url="jdbc:oracle:thin:@//oracle01-internal.local:1521/orcl01"

驱动类可能没有正确配置。

使用 oracle.jdbc.driver.OracleDriver 而不是 oracle.jdbc.OracleDriver

  <Resource name="jdbc/ToolSfDB" global="jdbc/ToolSfDB" auth="Container" type="javax.sql.DataSource"
          driverClassName="oracle.jdbc.driver.OracleDriver"
          url="jdbc:oracle:thin:@//oracle01-internal.local:1521/orcl01"

注意:确认oracle jar版本。它适用于 ojdbc6.jar

引用资料:

  1. hibernate cfg xml settings for derby oracle and h2
  2. difference between oracle jdbc driver classes
  3. configuring jdbc pool high concurrency

关于java - Spring 和 Hibernate 的事务管理使非 Activity 事务成为可能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35991750/

相关文章:

sql - 对列中的重复数据

java - 如何使用(正则表达式)删除java中的重复字母并且不区分大小写

java - 站长工具Api,获取超过1000个爬行错误

spring - 我们如何在 JDBC 中实现嵌套事务?

java - RAD 8 异常

linux - 如何修复 oracle TNS - 远程连接到数据库时连接超时错误?

java - 如何减少 Gwt 多入口点项目应用程序中的初始加载时间

JAVA:创建菜单循环

java - 希望根据 Spring Profile 编码不同的 POJO 字段集

java - Spring Boot 内存消耗增加超过 -Xmx 选项