I integrated Quartz2.2.2 with my Java EE application which is running in Weblogic 12.1.2. I want to handle all JTA transactions with my container (Weblogic).
But when an exception is occurred everything is rollbacked except for quartz transactions, I think the problem goes back to quartz.properties
here is my config file:
org.quartz.scheduler.instanceName = MyScheduler
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreCMT
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.oracle.weblogic.WebLogicOracleDelegate
org.quartz.jobStore.dataSource = quartz
org.quartz.threadPool.threadCount = 3
org.quartz.jobStore.nonManagedTXDataSource = quartz
org.quartz.dataSource.quartz.jndiURL = java.weblogic.datasources.quartz
I set both managed transactions' datasource and nonManaged one to the same datasource and it seems to be wrong! But I couldn't understand why I should set nonManagedTXDataSource
and this field is mandatory!
In documentation of quartz web site it is suggested that:
JobStoreCMT requires a (second) datasource that contains connections that will not be part of container-managed transactions. The value of this property must be the name of one the DataSources defined in the configuration properties file. This datasource must contain non-CMT connections, or in other words, connections for which it is legal for Quartz to directly call commit() and rollback() on.
Why I need such a datasource when I want all my transactons to be managed by the container!
Code example:
@Stateless
public class MyServiceHandlerBean {
@EJB
MyObjectManager objManager;
@EJB
MyScheduler scheduler;
public void addObj() throws MyException {
MyObject obj = new MyObject("fname","lastname");
objManager.save(obj);
scheduler.addJobForObj(obj);
}
}
and MyScheduler
class that works with quartz:
@LocalBean
@Stateless
public class MyScheduler {
private Scheduler scheduler = null;
public MyScheduler() throws SchedulerException {
scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.start();
}
public void addJobForObj(MyObject obj) throws MyException {
JobBuilder jobBuilder = newJob(BaseJob.class).withIdentity(obj.getId());
JobDetail job = jobBuilder.build();
try {
// Does something to create triggers
scheduler.scheduleJob(job, triggers, false);
} catch (SchedulerException e) {
throw new MyException("Something");
} catch (MyException e) {
throw e;
}
}
}
and here is MyException
class code:
@ApplicationException(rollback=true)
public class MyException extends Exception{
}
The problem is when I call MyServiceHandlerBean
method (addObj
) when save operation of MyObjectManager
fails container rolls transaction back but the job is added to the Database of quartz scheduler.
After a while I found that it was my mistake! Maybe this should be a comment but I think it can be more useful if I post it as an answer. My mistake was in the Weblogic data-source configuration. I should have enabled Support Global Transaction in the data-source transaction configuration.