随机获取“连接是只读的” - Spring

时间:2013-08-27 13:38:11

标签: spring hibernate jpa

我花了最近几天调试一些非常奇怪的错误。

我有一个公开的WebService,它调用名为“addNewOrder”的service-metod 此服务方法注释为 @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)

此服务方法需要读取和写入数据库。

我认为上面的注释会确保每次调用此方法时,我都会获得一个可以执行所需操作的新事务。

但是大约有50%的时间,当调用“addNewOrder”时,我会收到这些奇怪的错误:

org.hibernate.engine.jdbc.spi.SqlExceptionHelper:143 - SQL Error: 0, SQLState: S1009
org.hibernate.engine.jdbc.spi.SqlExceptionHelper:144 - Connection is read-only. Queries leading to data modification are not allowed

有没有人知道为什么会发生这种情况?为什么它是随机的?

我使用Spring 3.2.4,Hibernate 4.1.7,Mysql-connector 5.1.26

这是我的applicationContext片段:

<?xml version="1.0" encoding="iso-8859-1"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:tx="http://www.springframework.org/schema/tx"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">

<bean id="entityManagerFactory"
      class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="packagesToScan" value="no.aida.model"/>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="showSql" value="${jpa.show.sql}"/>
            <property name="generateDdl" value="${jpa.generate.ddl}"/>
            <property name="databasePlatform" value="${jpa.dialect}"/>
        </bean>
    </property>
    <property name="jpaDialect">
        <bean id="jpaDialect" class="no.aida.dao.hibernate.IsolationSupportHibernateJpaDialect" />
    </property>
</bean>

<!-- javax.sql.DataSource supplied by Jakarta Commons Connection Pooling -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${mysql.db.driver}"/>
    <property name="url" value="${mysql.db.url}"/>
    <property name="username" value="${mysql.db.username}"/>
    <property name="password" value="${mysql.db.password}"/>
    <property name="initialSize" value="3" />
    <property name="maxActive" value="30" />
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
    <property name="dataSource" ref="dataSource"/>
</bean>

<!-- Enable @Transactional support -->
<tx:annotation-driven transaction-manager="transactionManager"/>

</beans>

2 个答案:

答案 0 :(得分:1)

好吧,我会被诅咒。发帖后几分钟我终于找到了错误。它是随机的原因是因为我有另一个名为“getStatus”的服务方法,它以只读方式注释。如果调用此函数,那么使用相同连接的每个请求也将是只读的。但我仍然无法理解为什么在使用readOnly = false注释的方法上使用连接时不会重新设置只读...

并添加到传奇。没有重置连接的原因是因为我们已经实现了一个忘记重置连接的自定义JpaDialect ... doooooh!

答案 1 :(得分:-1)

value="${mysql.db.url}"

您能指定连接网址吗?你用的是:

failOverReadOnly=false
是不是?这应该有所帮助。

BR,伊利亚