With the latest version of Imixs-Workflow we support now a consistency Lucene search index coupled with the Java EE container based transaction concept.
Writing a Lucene Index during a Java EE transaction, coupled to JPA database operations, it becomes quickly difficult to keep the Lucene index consistent. The reason is that a lucene index can become inconsistency if you write the lucene index within a long running Java transaction. In case the transaction fails lately, there is no way to roll back the already written lucene index automatically. This is different to the build-in roll-back functionality of a SQL database which is only writing new data in case the transaction succeeds. Also clients reading the index before a running transaction is closed will read uncommitted index data which will lead to wrong search results.
In Version 4.4.0 of Imixs-Workflow we now solved this problem by implementing a Lucene Event Log mechanism. Instead of directly updating the Lucene index during the processing life-cycle, the Imixs-Workflow engine just creates a new eventLogEntry with JPA using the same container managed transaction context.
@Stateless
@LocalBean
public class LuceneUpdateService {
....
public void updateDocuments(Collection<ItemCollection> documents) {
// JPA work....
...
// Write the JPA eventLog entry indicating to update Lucene index
....
}
....
}
Now whenever a client calls the lucene search method, Imixs-Workflow will automatically run a flush method to update teh lucene index based on the latest event log entries:
@TransactionAttribute(value = TransactionAttributeType.REQUIRES_NEW)
public void flush() {
Query q = manager.createQuery("SELECT eventLog FROM EventLog AS eventLog" );
Collection<EventLog> result = q.getResultList();
if (result != null && result.size() > 0) {
for (EventLog eventLogEntry : result) {
.... update lucen index for each entry
.......
// remove the eventLogEntry.
manager.remove(eventLogEntry);
}
}
}
With the annotation TransactionAttributeType.REQUIRES_NEW the flush() method will only read already committed eventLog entries. So a client will only see committed updates in the Lucene Index. Even during a transaction from any other business method the lucene will not include ‘uncommitted’ documents. This behavior is equals to the transaction model ‘Read Committed’.
See also the similar discussion at: How making stateless session beans transaction-aware?
The Search Functionality of Imixs-Workflow
If you work with the Imixs-Workflow engine you don’t have to deal with writing the lucene index by yourself. Imixs-Workflow hides this complexity for your if you call for example the process method from the WorkflowService:
@EJB
private WorkflowService workflowService;
....
// create a new workitem assigned to a workflow model
ItemCollection workitem=new ItemCollection().model("1.0.0").task(100).event(10);
// assign business data
workitem.replaceItemValue("_customer","M. Melman");
workitem.replaceItemValue("_ordernumber",20051234);
// process the workitem
workitem = workflowService.processWorkItem(workitem);
....
You will find more details about how to use the search functionality of Imixs-Workflow here.
