Skip to content

Commit

Permalink
[JBPM-10209] Switching to CMT
Browse files Browse the repository at this point in the history
  • Loading branch information
fjtirado committed Nov 14, 2023
1 parent f897fcc commit 87a869a
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,15 @@
import javax.ejb.Lock;
import javax.ejb.LockType;
import javax.ejb.NoSuchObjectLocalException;
import javax.ejb.SessionContext;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerConfig;
import javax.ejb.TimerHandle;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.transaction.RollbackException;
Expand All @@ -58,8 +61,6 @@

@Singleton
@Startup
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
@TransactionManagement(TransactionManagementType.BEAN)
@Lock(LockType.READ)
public class EJBTimerScheduler {

Expand All @@ -77,10 +78,11 @@ public class EJBTimerScheduler {

@Resource
protected javax.ejb.TimerService timerService;

@Resource
protected SessionContext ctx;

@Resource
protected UserTransaction utx;


public void setUseLocalCache(boolean useLocalCache) {
this.useLocalCache = useLocalCache;
}
Expand Down Expand Up @@ -117,7 +119,7 @@ public void executeTimerJob(Timer timer) {
}
}
try {
transaction(this::executeTimerJobInstance, timerJobInstance);
invokeTransaction(this::executeTimerJobInstance, timerJobInstance);
} catch (SessionNotFoundException e) {
logger.warn("Process instance is not found. More likely already completed. Timer {} won't be recovered", timerJobInstance, e);
removeUnrecoverableTimer(timerJob, timer);
Expand All @@ -141,7 +143,7 @@ private void removeUnrecoverableTimer(EjbTimerJob ejbTimerJob, Timer timer) {
logger.warn("Session not found for timer {}. Timer could not removed.", ejbTimerJob.getTimerJobInstance());
}
};
transaction(tx, ejbTimerJob.getTimerJobInstance());
invokeTransaction(tx, ejbTimerJob.getTimerJobInstance());
} catch (Exception e1) {
logger.warn("There was a problem during timer removal {}", ejbTimerJob.getTimerJobInstance(), e1);
}
Expand Down Expand Up @@ -169,7 +171,7 @@ private void recoverTimerJobInstance(EjbTimerJob ejbTimerJob, Timer timer, Excep
logger.debug("Interval trigger {} was removed before rescheduling", ejbTimerJob.getTimerJobInstance());
}
};
transaction(tx, ejbTimerJob.getTimerJobInstance());
invokeTransaction(tx, ejbTimerJob.getTimerJobInstance());
} catch (Exception e1) {
logger.warn("Could not schedule the interval trigger {}", ejbTimerJob.getTimerJobInstance(), e1);
}
Expand Down Expand Up @@ -198,7 +200,7 @@ private void recoverTimerJobInstance(EjbTimerJob ejbTimerJob, Timer timer, Excep
((GlobalJpaTimerJobInstance) ejbTimerJob.getTimerJobInstance()).setExternalTimerId(getPlatformTimerId(newTimer));
};
try {
transaction(operation, ejbTimerJob.getTimerJobInstance());
invokeTransaction (operation, ejbTimerJob.getTimerJobInstance());
} catch (Exception e1) {
logger.error("Failed to executed timer recovery {}", e1.getMessage(), e1);
}
Expand All @@ -218,30 +220,16 @@ private boolean isSessionNotFound(Exception e) {

@FunctionalInterface
private interface Transaction<I> {

void doWork(I item) throws Exception;
}

private <I> void transaction(Transaction<I> operation, I item) throws Exception {
try {
utx.begin();
operation.doWork(item);
utx.commit();
} catch(RollbackException e) {
logger.warn("Transaction was rolled back for {} with status {}", item, utx.getStatus());
if(utx.getStatus() == javax.transaction.Status.STATUS_ACTIVE) {
utx.rollback();
}
throw new RuntimeException("jbpm timer has been rolledback", e);
} catch (Exception e) {
try {
utx.rollback();
} catch (Exception re) {
logger.error("transaction could not be rolled back", re);
}

throw e;
}
@TransactionAttribute(value = TransactionAttributeType.REQUIRES_NEW)
public <I> void transaction(Transaction<I> operation, I item) throws Exception {
operation.doWork(item);
}

private <I> void invokeTransaction (Transaction<I> operation, I item) throws Exception {
ctx.getBusinessObject(EJBTimerScheduler.class).transaction(operation,item);
}

public void internalSchedule(TimerJobInstance timerJobInstance) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,34 +99,12 @@ public JobHandle scheduleJob(Job job, JobContext ctx, Trigger trigger) {

@Override
public boolean removeJob(JobHandle jobHandle) {
String uuid = ((EjbGlobalJobHandle) jobHandle).getUuid();
final Timer ejbTimer = getEjbTimer(getTimerMappinInfo(uuid));
final Timer ejbTimer = getEjbTimer(getTimerMappinInfo(((EjbGlobalJobHandle) jobHandle).getUuid()));
if (TRANSACTIONAL && ejbTimer == null) {
// this situation needs to be avoided as it should not happen
return false;
}
JtaTransactionManager tm = (JtaTransactionManager) TransactionManagerFactory.get().newTransactionManager();
try {
tm.registerTransactionSynchronization(new TransactionSynchronization() {
@Override
public void beforeCompletion() {
}

@Override
public void afterCompletion(int status) {
if (status == TransactionManager.STATUS_COMMITTED) {
logger.debug("remove job {} after commited", jobHandle);
scheduler.removeJob(jobHandle, ejbTimer);
}
}

});
logger.debug("register tx to remove job {}", jobHandle);
return true;
} catch (Exception e) {
logger.debug("remove job {} outside tx", jobHandle);
return scheduler.removeJob(jobHandle, ejbTimer);
}
return scheduler.removeJob(jobHandle, ejbTimer);
}

private TimerJobInstance getTimerJobInstance (String uuid) {
Expand Down

0 comments on commit 87a869a

Please sign in to comment.