[wildfly-dev] (transaction enlistment for ACID but none for BASE...) update on WildFly NoSQL prototype integration...

Scott Marlow smarlow at redhat.com
Wed Jul 20 09:59:52 EDT 2016



On 07/20/2016 06:02 AM, Gytis Trikleris wrote:
> Scott,
>
> I think that this wouldn’t be a common case, but it is still possible
> that user could inject drivers from two different profiles and invoke
> them in the same transaction.
In this case two Neo4jXAResourceImpl
> instances would be enlisted to the transaction and that is not a
> recommended use case because atomicity cannot be guaranteed. There is a
> bit more info about it in section 3.2.1.1.
> of http://narayana.io/docs/product/index.html.

I'm trying to understand how the description in 3.2.1.1 applies to 
Neo4jXAResourceImpl (implements org.jboss.tm.LastResource and not 
com.arjuna.ats.jta.resources.LastResourceCommitOptimisation).


By default, will WildFly allow more than one org.jboss.tm.LastResource 
to be enlisted into the JTA transaction at a time?  When you say above 
that its possible for two Neo4jXAResourceImpl's to be injected, would 
that only be if com.arjuna.ats.jta.allowMultipleLastResources is changed 
to true?

Thanks for pointing this case out!

Scott

>
> Gytis
>
>> On 19 Jul 2016, at 19:36, Scott Marlow <smarlow at redhat.com
>> <mailto:smarlow at redhat.com>> wrote:
>>
>>
>>
>> On 07/19/2016 10:49 AM, Scott Marlow wrote:
>>>
>>>
>>> On 07/19/2016 04:17 AM, Emmanuel Bernard wrote:
>>>> On Mon 2016-07-18 12:20, Scott Marlow wrote:
>>>>> Thanks for the feedback.
>>>>>
>>>>> On 07/18/2016 09:24 AM, Emmanuel Bernard wrote:
>>>>>> I'm lost.
>>>>>>
>>>>>> What is the expected code a developer will write ?
>>>>>>
>>>>>> If that' something along the lines of:
>>>>>>
>>>>>> jta.beginTx() // declaratively or imperatively
>>>>>> neo4j.beginTx()
>>>>>> ...
>>>>>> neo4j.commit()
>>>>>> jta.commit() //declaratively or imperatively
>>>>>
>>>>> They are not limited to writing the above code.  In addition, the
>>>>> developer
>>>>> can also avoid calling neo4j.beginTx()/neo4j.commit(). Something like:
>>>>>
>>>>> jta.beginTx() // declaratively or imperatively
>>>>> session = driver.session() // internally does
>>>>> session.beginTransaction()
>>>>> ...
>>>>> jta.commit() //declaratively or imperatively
>>>>>
>>>>> The calls to neo4j.beginTx()/commit() are ignored.
>>>>>
>>>>> The choice of ignoring those calls, is made against the alternative of
>>>>> throwing an exception.  The reason for ignoring the neo4j transactional
>>>>> calls, is to be more compatible with existing ne04j code that may
>>>>> be using
>>>>> the neo4j transactional code, with the goal that the JTA transaction
>>>>> controls the underlying ne04j transaction.  Neo4j transactional
>>>>> code also
>>>>> runs the statements against the neo4j transaction class, instead of the
>>>>> neo4j session class.
>>>>
>>>> You mean having existing code work with the new JTA transaction net?
>>>> I don't think you can safely support that. What if the code does
>>>>
>>>> @Transactional
>>>> public void doThings() {
>>>>   session = drive.session();
>>>>   session.beginTransaction();
>>> // should be:
>>> Transaction transaction = session.beginTransaction();
>>>>   try {
>>>>       // do things
>>>>   catch (Exception e) {
>>>>       // swallow exception because we will fix things
>>>>       session.rollback();
>>> // should be:
>>>          transaction.failure();
>>>>       session.beginTransaction();
>>>          transaction = session.beginTransaction();
>>>>       // do something else
>>>>       session.commit();
>>>>    }
>>>> }
>>>>
>>>> Such an existing code won't work if JTA in involved and
>>>> session.beginTrnasaction() / commit() are ignored.
>>>
>>> With the current prototype, the above existing code won't work as
>>> originally intended (with regard to what the original developer had in
>>> mind) with JTA enlistment.
>>>
>>>>
>>>> So only code written with the idea of the JTA net in mind will be safe.
>>>
>>> Clearly, any existing neo4j code that expects to fail the current neo4j
>>> transaction, then start a new neo4j transaction to fix things, will not
>>> work in the JTA net.  As the fixing of things in the JTA net, needs to
>>> occur before marking the JTA transaction for rollback only *or* by
>>> fixing things after the JTA transaction rolls back.
>>>
>>> Are there any other holes that come to mind, with regard to existing
>>> neo4j transaction code that won't work as original intended in the
>>> JTA net?
>>>
>>>>
>>>>>>
>>>>>> then I find it very user unfriendly to force the code to call both Tx
>>>>>> APIs. It should be one or the other.
>>>>>
>>>>> Do you really want to rewrite your neo4j code to avoid the neo4j tx
>>>>> APIs
>>>>> when enlisted into a JTA transaction?  Or should the neo4j tx API
>>>>> calls be
>>>>> ignored when enlisted into a JTA transaction (as we are doing now)?
>>>>
>>>> See my above example of already existing code.
>>>>
>>>> For new code that you want to run both in SE and Wildfly, that's an
>>>> interesting question but how would you do it in practice? A try catch
>>>> but rethrowing the exception in case JTA is involved and needs to be
>>>> notified of the tx rollback?
>>>
>>> The developer could rewrite their "workaround tx failure" code to avoid
>>> further calls to the neo4j tx api, but this is kind of bad as they only
>>> should do this when the neo4j transaction is enlisted into the JTA
>>> transaction, but not when enlistment is disabled.  Some neo4j connection
>>> profiles will be configured to allow JTA enlistment (transaction=1pc)
>>> and some will be configured to not allow JTA enlistment
>>> (transaction=none), so we can expect common application code will likely
>>> be reused for both JTA + non-JTA.  Seems to me that SE is always the
>>> same as the WildFly neo4j connection profile with "transaction=none", so
>>> we have the same problem with SE + WildFly, trying to run the same user
>>> code that is expected to work with JTA enlistment (neo4j connection
>>> profile has "transaction=1pc").
>>>
>>> I don't know of any CDI magic that helps, as if we add support for
>>> inject of a javax.transaction.TransactionScoped neo4j session, that
>>> works the same as a session obtained from Driver.session().
>>>
>>>> I'm interested to see concrete code because if doable, it will have lots
>>>> of constraints and be limited to very specific patterns of code I think.
>>>> But again, let's show each other code.
>>
>> I found some examples in the Neo4j Java driver unit tests.  I started a
>> gist [1] that lists a few of the test cases that I thought were
>> interesting for this discussion about "compatibility of existing Neo4j
>> tx handling code in the JTA net".
>>
>> In actual applications, the use cases will not be so simple.  Instead,
>> we will see many different patterns mixed over several lines of
>> application library code, however, each unit case noted is presenting a
>> different example that would probably not run as is, when enlisted in a
>> JTA transaction.
>>
>> This doesn't mean it is bad to enlist Neo4j transactions into a JTA
>> transaction, it just means that it is bad assume that a Neo4j tx works
>> the same when enlisted in a JTA transaction.
>>
>> I think that a challenge here for us, is to deduce what our rules should
>> be when enlisting Neo4j transactions into a JTA transaction, with regard
>> to what the application can expect and shouldn't expect.
>>
>> Scott
>>
>> [1] https://gist.github.com/scottmarlow/2779d21653e8466d85e38c1d62d4bb1e
>>
>>>
>>> That should help us explore the compatibility with existing code idea
>>> and pick which approach to use (e.g. whether explicit neo4j transaction
>>> use in a JTA enlisted transaction should throw an exception or ignore
>>> the explicit transaction use as we are doing now in the prototype).
>>>
>>> Should we also post on https://groups.google.com/forum/#!forum/neo4j
>>> <https://groups.google.com/forum/#%21forum/neo4j> to
>>> ask for input on JTA enlistment?
>>>
>>>>
>>>> Emmanuel
>>>>
>>> _______________________________________________
>>> wildfly-dev mailing list
>>> wildfly-dev at lists.jboss.org <mailto:wildfly-dev at lists.jboss.org>
>>> https://lists.jboss.org/mailman/listinfo/wildfly-dev
>>>
>> _______________________________________________
>> wildfly-dev mailing list
>> wildfly-dev at lists.jboss.org <mailto:wildfly-dev at lists.jboss.org>
>> https://lists.jboss.org/mailman/listinfo/wildfly-dev
>


More information about the wildfly-dev mailing list