Friday, February 13, 2009

Drools goes Transactional

The last bit of work for Drools 5.0 is almost in place, where units of work can now be made transactionally. Here is a quick unit test that shows two transactions, the later with a rollback, notice the rolled back insertion does not have any affect. Statements executed outside of the user defined transaction block grab a transaction just for that single command, which is what happens with the fireAllRules(). This work was necessary so that we can combine rules and flow together but make sure those state changes are transactional. The rules side is quite heavy, but it should be fine for a small number of facts, where network latency of the DB will be the bottleneck.

rule addInteger
when
$i : Integer( intValue > 1 )
then
list.add( $i );
end

KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add( ResourceFactory.newByteArrayResource( str.getBytes() ),
ResourceType.DRL );
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();

if ( kbuilder.hasErrors() ) {
fail( kbuilder.getErrors().toString() );
}

kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );

StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession( conf );

List list = new ArrayList();
UserTransaction ut = (UserTransaction) new InitialContext().lookup( "java:comp/UserTransaction"
ut.begin();
ksession.setGlobal( "list",
list );
ksession.insert( 1 );
ksession.insert( 2 );
ut.commit();

ut.begin();
ksession.insert( 3 );
ut.rollback();

ksession.fireAllRules();

assertEquals( 2,
list.size() );

2 comments:

  1. Why do you grab a reference to UserTransaction again after commit? The instance returned the first time isn't going away because commit was called, so you can use it again.

    ReplyDelete
  2. it's a unit test, just got left in from copy/pasting.

    ReplyDelete