2013-08-27 48 views
1

我花了最近幾天調試一些非常奇怪的錯誤。獲得隨機「連接是隻讀」 - 春天

我有一個暴露的WebService它調用服務梅託德稱爲「addNewOrder」 這種服務方法都添加了 @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,4.1.7的Hibernate,Mysql的連接器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> 
+1

那麼我會被詛咒。發佈這張照片後,我終於找到了錯誤。它是隨機的原因是因爲我有另一個名爲「getStatus」的服務方法,它是通過只讀註釋的。如果這被調用,那麼使用相同連接的每個請求也將是隻讀的。但我仍然不能理解爲什麼只讀方法在連接用於使用readOnly = false註釋的方法時不會重新設置... – user829237

+0

並添加到傳說中。之所以沒有重新設置連接,是因爲我們實現了一個自定義的JpaDialect,它忘記了重置連接...... doooooh! – user829237

回答

1

嗯,我會被定罪。發佈這張照片後,我終於找到了錯誤。它是隨機的原因是因爲我有另一個名爲「getStatus」的服務方法,它是通過只讀註釋的。如果這被調用,那麼使用相同連接的每個請求也將是隻讀的。但我仍然不能理解爲什麼只讀連接時使用readOnly = false註釋的方法不會重新設置...

並添加到傳奇。之所以沒有重新設置連接,是因爲我們實現了一個自定義的JpaDialect,它忘記了重置連接...... doooooh!

+0

謝謝!對我來說,這種情況 – tuxSlayer

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

您能否指定連接url?您是否使用:

failOverReadOnly=false 

還是不是?這應該有所幫助。

BR,伊利亞

+0

隱藏錯誤沒有幫助:) – tuxSlayer