web-dev-qa-db-ja.com

Spring Batch ORA-08177:単一ジョブ、SERIALIZED分離レベルを実行している場合、このトランザクションのアクセスをシリアル化できません

Spring BatchのJobRepositoryのSERIALIZED分離レベルでこの例外が発生しています:

org.springframework.dao.CannotSerializeTransactionException: PreparedStatementCallback; SQL [INSERT into DATAFEED_APP.BATCH_JOB_INSTANCE(JOB_INSTANCE_ID, JOB_NAME, JOB_KEY, VERSION) values (?, ?, ?, ?)]; ORA-08177: can't serialize access for this transaction

;ネストされた例外はJava.sql.SQLException:ORA-08177:このトランザクションのアクセスをシリアル化できません

at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.Java:269)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.Java:72)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.Java:603)
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.Java:812)
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.Java:868)
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.Java:872)
at org.springframework.batch.core.repository.dao.JdbcJobInstanceDao.createJobInstance(JdbcJobInstanceDao.Java:105)
at org.springframework.batch.core.repository.support.SimpleJobRepository.createJobExecution(SimpleJobRepository.Java:135)
at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:39)
at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:25)
at Java.lang.reflect.Method.invoke(Method.Java:597)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.Java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.Java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.Java:110)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:172)
at org.springframework.batch.core.repository.support.AbstractJobRepositoryFactoryBean$1.invoke(AbstractJobRepositoryFactoryBean.Java:172)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.Java:204)
at $Proxy27.createJobExecution(Unknown Source)
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.Java:124)
at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:39)
at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:25)
at Java.lang.reflect.Method.invoke(Method.Java:597)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.Java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.Java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:150)
at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.Java:117)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.Java:204)
at $Proxy61.run(Unknown Source)

1つのジョブのみを実行する場合、他に何も並行して実行されません。 JobRepositoryの分離レベルをISOLATION_READ_COMMITTEDに変更すると、例外はなくなりました。

この例外の理由は何ですか?

19
padis

公式ドキュメント-4.3.1 から

そのメソッドのデフォルトの分離レベルはSERIALIZABLEです。これは非常に積極的です。READ_COMMITTEDも同様に機能します。 2つのプロセスがこの方法で衝突する可能性が低い場合、READ_UNCOMMITTEDは問題ありません。ただし、create *メソッドの呼び出しは非常に短いため、データベースプラットフォームがサポートしている限り、SERIALIZEDが問題を引き起こす可能性は低いです

8

私は同じ問題を抱えていました、そして実際にはjobRepositoryレベルでの分離が重要です。ここに私のために働くコードの例を示します:

<batch:job-repository id="jobRepository"
    data-source="dataSource" transaction-manager="transactionManager"
    isolation-level-for-create="READ_COMMITTED" table-prefix="SB_" />   
7

シリアル化されたトランザクションを使用する場合は、 Oracle Docs ごとにテーブルのinitransパラメーターを増やす必要があります。シリアル化されたトランザクションを処理するには、3以上にする必要があります。

alter table BATCH_.... INITRANS 3
5
mpkorstanje

INI_TRANSを100にジャッキアップしようとしましたが、まだ問題が発生していました

ROWDEPENDENCIESをテーブルの作成に追加することを提案するこの記事を見つけました。

http://www.devx.com/dbzone/Article/41591?pf=true

INI_TRANSと現在のROWDEPENDENCIESを使用する私にとって、Serializedの例外はなくなりました。

更新:完全なソリューションではないことが判明しました。このシリアル化された例外のイベントが一晩で発生しました。単一の障害が発生する前に何百回も実行されたので、これははるかに優れていますが、ROWDEPENDENCIESを使用することはまだ完全なソリューションではないようです。

3
grbonk

この問題の回避策があります。

以下の手順に従ってください。

  1. データベースにテーブルを手動で作成します( Link )。
  2. BATCH_JOB_INSTANCEBATCH_JOB_EXECUTION、およびBATCH_JOB_EXECUTION_PARAMSテーブルにいくつかのダミーレコードを挿入します。 (コミットすることを忘れないでください)
  3. エラーが解決しました。楽しい。
1
Raj Kumar Gupta

以下のようにisolationLevelForCreateを追加することで、このエラーを解決できました。

<bean id="jobRepository" class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
        <property name="databaseType" value="Oracle"/>
        <property name="dataSource" ref="dataSource" />
        <property name="transactionManager" ref="transactionManager" />
        <property name="isolationLevelForCreate" value="ISOLATION_READ_UNCOMMITTED"/>
    </bean>
0
Bajal