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

Gytis Trikleris gtrikler at redhat.com
Wed Jul 20 10:50:09 EDT 2016


The specific marker interface for it is overridable. See https://github.com/wildfly/wildfly/blob/master/transactions/src/main/java/org/jboss/as/txn/service/JTAEnvironmentBeanService.java#L58 where it is set to org.jboss.tm.LastResource.
No, by default it will not add the second resource but it can be allowed by changing the config. However, it will still print the warning.

Gytis

> On 20 Jul 2016, at 14:59, Scott Marlow <smarlow at redhat.com> wrote:
> 
> 
> 
> 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