ここ数日、本当に奇妙なエラーのデバッグに費やしてきました。
「addNewOrder」というサービスメソッドを呼び出す公開された WebService があります。このサービスメソッドには注釈が付けられています
@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>