[wildfly-dev] (transaction enlistment for ACID but none for BASE...) update on WildFly NoSQL prototype integration...
Scott Marlow
smarlow at redhat.com
Tue Jul 12 11:36:10 EDT 2016
On 07/11/2016 01:38 PM, Jesper Pedersen wrote:
> Hi,
>
> On 07/08/2016 12:24 PM, Scott Marlow wrote:
>> The NoSQL prototype now has transaction enlistment for Neo4j (one phase
>> wrapper).
>>
>> Test example link [1] shows a CMT test bean method
>
> You should add a comment that tx.success() / tx.failure() is tied to the
> out-come of the JTA transaction. And tx.close() is done in afterCompletion.
Comment added, thanks for noticing the absence. :)
>
>> and [2] shows a BMT test bean method.
>>
>
> This test case highlights the problem of checking for enlistment in 2
> places, as the Session is obtained before the transaction is started,
> and there is no way to get the session reference from the transaction
> instance.
>
> So, you can manage the transaction lifecycle, but not the session
> lifecycle.
In [1], when we get the Neo4j Session, we enlist it within the JTA
transaction. We also enlist the Neo4j transaction at the same time
(during the call to Driver.session() inside of a JTA transaction.) For
the duration of the JTA transaction, attempts to get the
Session/Transaction for the named Neo4j profile, will return the already
JTA enlisted Session/Transaction.
>
>> Currently, in a JTA transaction the Neo4j Session survives ending the
>> JTA transaction. It might be better to close the Neo4j Session when the
>> JTA transaction ends, which would require the application to get a new
>> Session, this would ensure that applications don't forget to close the
>> session, with the down side that with BMT, application code would need
>> to call the Neo4j Driver.session(), to get a new Session instance after
>> each JTA transaction ends. After a session is closed, there is no
>> guarantee that another session can be obtained, as the next
>> Driver.session() may time out if the internal pool of Driver sessions,
>> is empty and the configured time limit
>> (neo4j.driver.acquireSessionTimeout) is exceeded (defaults to 30
>> seconds). So, there are costs to automatically closing Neo4j Sessions
>> at JTA transaction end time. Although, you could say that closing the
>> Session, after each transaction, gives other threads a change to use the
>> Session that isn't really closed, but instead is really returned to the
>> internal Driver sessions pool.
>
> As you are enlisting the Neo4J resources into the transaction, I think
> that you should define driver.session() as the enlistment barrier, and
> therefore also close the session in afterCompletion.
I pushed an update [1] that includes auto closing the session, when the
transaction ends.
I didn't add a Synchronization yet, to handle closing the session when
the transaction manager doesn't call XAResourceWrapper.commit/rollback.
I agree that will introduce an extra layer of safety to ensure that
resources are closed.
>
> That makes it more clear in what scenarios the resources are managed.
>
> In JDBC you inject the DataSource instance, and obtain a Connection, so
> it would be parallel to this case Driver vs. Session.
>
> This means that people needs to be more careful in the BMT case to get
> the Session within an active transaction. JCA has
> CachedConnectionManager to verify these cases, so you could add a
> similar concept.
Attempts to call Neo4j transaction/session "close", within the JTA
transaction are ignored. How about calls to "close" after the JTA
transaction ends, should they also be ignored? Is there a JCA
equivalent of ignoring "close" after the transaction ends? I think that
Hibernate ORM is or was, closing DataSource's after the transaction
ends, so I assume that JCA ignores "close" after the JTA transaction ends.
Thanks again for the feedback!
Scott
[1]
https://github.com/scottmarlow/wildfly/commit/bfecbe881e6a16548b9712b3e52ff7acdd3142b4
More information about the wildfly-dev
mailing list