Seam & Hibernate(JDBCからSQLServer)で動作するSeam Webアプリケーションがあります。SeamとHibernateでトランザクションを再試行する最良の方法
これはうまくいきますが、重い負荷(JMeterのストレステスト)の下では、LockAcquisitionException
またはOptimisticLockException
があります。
LockAquisitionException
がSQLServerException
によって引き起こされる「別のプロセスでロックリソースにデッドロックし、デッドロックの対象として選択されたトランザクション(プロセスID 64)。再実行トランザクション」。
私はその後LockAquisitionException
のために、このようなトランザクションを再実行するようSeamインターセプタを書いた:
@AroundInvoke
public Object aroundInvoke(final InvocationContext invocationContext) throws Exception {
if (instanceThreadLocal.get() == null && isMethodInterceptable(invocationContext)) {
try {
instanceThreadLocal.set(this);
int i = 0;
PersistenceException exception = null;
do {
try {
return invocationContext.proceed();
} catch (final PersistenceException e) {
final Throwable cause = e.getCause();
if (!(cause instanceof LockAcquisitionException)) {
throw e;
}
exception = e;
i++;
if (i < MAX_RETRIES_LOCK_ACQUISITION) {
log.info("Swallowing a LockAcquisitionException - #0/#1", i, MAX_RETRIES_LOCK_ACQUISITION);
try {
if (Transaction.instance().isRolledBackOrMarkedRollback()) {
Transaction.instance().rollback();
}
Transaction.instance().begin();
} catch (final Exception e2) {
throw new IllegalStateException("Exception while rollback the current transaction, and begining a new one.", e2);
}
Thread.sleep(1000);
} else {
log.info("Can't swallow any more LockAcquisitionException (#0/#1), will throw it.", i, MAX_RETRIES_LOCK_ACQUISITION);
throw e;
}
}
} while (i < MAX_RETRIES_LOCK_ACQUISITION);
throw exception;
} finally {
instanceThreadLocal.remove();
}
}
return invocationContext.proceed();
}
最初の質問:はこのインターセプタが正しく仕事をするあなたと思いますか?周りとグーグルによって
は Alfresco( with a forum talk here)、 Bonitaと Orchestraがあまりにも、このようなトランザクションを再実行するためにいくつかのメソッドを持っていることを見て、彼らは、例えばStaleObjectStateException
(私の
OptimisticLockException
の原因)のように、より多くの例外をキャッチしています。
私の第二の質問は、次のとおりです。それは問題だとしてStaleObjectStateException
(は「行が更新または削除別のトランザクションによって(または保存されていないと値のマッピングが間違ってあった)」)のために、normalyあなただけ、トランザクションを再実行することはできませんデータベースとの同期と@Version
フィールドではありませんか? Alfrescoがそのような例外によって引き起こされたトランザクションを再実行しようとする理由は何ですか?
EDIT:SQLServerException
によって引き起こさLockAcquisitionException
については 、私はウェブ上でいくつかのいくつかのリソースを見てきた、と私は私のコードを再確認した場合でも、それはとにかく起こったことを思わ...ここのリンクは以下のとおりです。
- Microsoft talking about that on support.microsoft.com :サブリンクで
- Another article(それはまた、リソースが不足によって起こった可能言うcomment付き)
でもMicrosoftはデッドロックを最小限に抑えることができますが」は、彼らは完全に回避することができないと言います。フロントエンド・アプリケーションは、デッドロックを処理するように設計されなければならない理由がある。トランザクション(プロセスID 64)のロックリソースを別のプロセスがデッドロックしたと選択されている「