[wildfly-dev] update on WildFly NoSQL prototype integration...

Jesper Pedersen jesper.pedersen at redhat.com
Tue May 10 11:06:13 EDT 2016


Hi,

On 05/10/2016 09:58 AM, Scott Marlow wrote:
> On 05/05/2016 01:48 PM, Jesper Pedersen wrote:
>>> 6. transaction enlistment
>>>
>>
>> This will vary for each store, and there are many loopholes that you may
>> want to plug, f.ex. sharing a connection between 2 transactions.
>>
>> For 1-phase, you will have to insert a LocalXAResource instance into the
>> transaction when the "connection" is obtained, and return it on the
>> boundary (afterCompletion). Same deal for 2-phase basically.
>>
>> The LocalXAResource implementation will of course be different for each
>> store.
>
> Any links to existing IronJacamar code to share here?  I think that we
> could prototype new transaction enlistment handling code, based on what
> we currently have.
>

The IronJacamar code is here for Narayana:

https://github.com/ironjacamar/ironjacamar/tree/master/core/src/main/java/org/ironjacamar/core/tx/narayana

However, that is based on the Java EE Connector Architecture 
specification, so we have a *much* easier job.

Lets take an example from the NoSQL world using Neo4J:

http://neo4j.com/docs/api/java-driver/current/org/neo4j/driver/v1/Driver.html

...neo4j.LocalXAResource implements XAResource, org.jboss.tm.LastResource

  public void start(Xid xid, int flags) throws XAException {
    tx = session.beginTransaction();
  }

  public void commit(Xid xid, boolean onePhase) throws XAException {
    tx.success();
  }

  public void rollback(Xid xid) throws XAException {
    tx.failure();
  }

And the app, f.ex. in a SLSB method

public class MySLSB ...

   @Resource(mappedName="java:jboss/nosql/neo4j")
   private Driver neo4j;

   public void myMethod() {
#1   Session s = neo4j.createSession();
      s.run( "CREATE (n {name:'Bob'})" );

#2   Transaction tx = s.beginTransaction();
      tx.run( "CREATE (n {name:'Alice'})" );
      tx.run( "CREATE (n {name:'Tina'})" );

#3   tx.success();

#4   tx.close();
#5   s.close();
#6   neo4j.close();
   }

However, as you can see there are a number of hidden things going on 
here if ".../neo4j" is deployed as "transaction=1phase".

#1: Here you have to intercept the call, create the LocalXAResource 
instance and enlist it in the active transaction

#2: Here you have to a delegator instance that only executes the run() calls

#3: No-op call, happens upon EE transaction completion

#4: No-op call. happens upon EE transaction completion

#5: No-op call, happens in an enlisted Synchronization instance 
(afterCompletion) (done in #1 too)

#6: No-op call, handled by subsystem

The value-add is that #3 is tied into the overall EE transaction.

If ".../neo4j" is deployed as "transaction=none", then all calls are on 
the "real" Neo4J objects.

As you can see it isn't as simple as it may appear, and application flow 
could be different from what the developer expects, as #3 could be a 
real tx.failure() call in case of MARKED_FOR_ROLLBACK.

There are def pros/cons of doing tx enlistment for this area...

>>
>> You may want a transaction option for the stores that supports this such
>> that people can choose the "level" of enlistment (ala jta="false").
>>
>> One task I see is that people will have access to the transactional
>> methods in the API, and you don't want them to call these methods in
>> their apps unless the transaction setting allows this.
>>
>> I think you can leave out the corner-cases in the 1st iteration, like
>> deferred enlistment (get connection, start transaction).

Best regards,
  Jesper



More information about the wildfly-dev mailing list