protected void addInterceptors(KieSession ksession) { PersistableRunner runner = (PersistableRunner) ((CommandBasedStatefulKnowledgeSession) ksession).getRunner(); runner.addInterceptor(new OptimisticLockRetryInterceptor()); // even though it's added always TransactionLockInterceptor is by default disabled so won't do anything runner.addInterceptor(new TransactionLockInterceptor(ksession.getEnvironment())); runner.addInterceptor(new ExecutionErrorHandlerInterceptor(ksession.getEnvironment())); }
assertEquals(TransactionLockInterceptor.class, internalCommandService.getClass()); internalCommandService = (ChainableRunner) ((TransactionLockInterceptor) internalCommandService).getNext(); assertEquals(OptimisticLockRetryInterceptor.class, internalCommandService.getClass());
@Override public RequestContext execute( Executable executable, RequestContext ctx ) { if (!active) { executeNext(executable, ctx); return ctx; } // release before entering in case it failed previously to avoid deadlock releaseAfterFailure(); // proceed only when explicitly activated boolean locked = false; if (!lock.isHeldByCurrentThread()) { logger.debug("About to get a lock on command service by {}", Thread.currentThread().getName()); lock.lock(); locked = true; logger.debug("Lock taken by {}", Thread.currentThread().getName()); } try { executeNext(executable, ctx); } finally { if (locked) { logger.debug("About to register lock release handler by {}", Thread.currentThread().getName()); release((TransactionManager) environment.get(EnvironmentName.TRANSACTION_MANAGER)); } releaseAfterFailure(); } return ctx; }
protected void releaseAfterFailure() { if (forceUnlock.remove(Thread.currentThread().getId())) { logger.debug("Forcibly unlocking as it was requested by a reaper thread (transaction timeout)"); doRelease(); } }
@Override public void afterCompletion(int status) { if (isRollback(status)) { final long currentThreadId = Thread.currentThread().getId(); final boolean isRegistrationThread = currentThreadId == registrationThreadId; if ( ! isRegistrationThread ) { logger.debug("Attempt to unlock from different thread {} while owner is {}, requesting force unlock", currentThreadId, registrationThreadId ); forceUnlock.add(registrationThreadId); return; } } doRelease(); }
protected void release(TransactionManager txm) { try { TransactionManagerHelper.registerTransactionSyncInContainer(txm, new ReleaseLockTransactionSynchronization(Thread.currentThread().getId(), 100, releaseTxKey)); } catch (Throwable e) { logger.debug("Error happened releasing directly by {} due to {}", Thread.currentThread().getName(), e.getMessage()); doRelease(); } }
protected void addInterceptors(KieSession ksession) { PersistableRunner runner = (PersistableRunner) ((CommandBasedStatefulKnowledgeSession) ksession).getRunner(); runner.addInterceptor(new OptimisticLockRetryInterceptor()); // even though it's added always TransactionLockInterceptor is by default disabled so won't do anything runner.addInterceptor(new TransactionLockInterceptor(ksession.getEnvironment())); runner.addInterceptor(new ExecutionErrorHandlerInterceptor(ksession.getEnvironment())); }