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
then I find it very user unfriendly to force the code to call both Tx
APIs. It should be one or the other.
On Wed 2016-07-13 15:05, Scott Marlow wrote:
Hi Gunnar/Emmanuel,
The Ne04j profile can either be "transaction=1pc" (JTA transaction enlisted)
or "transaction=none" (will not be enlisted into JTA transaction). I think
this covers what Emmanuel suggested (I didn't get Emmanuel's email yet for
some unknown reason).
It sounds like we aren't yet connecting on what the WF Neo4j profile is
doing, so I'll respond below and we can continue from there. :)
On 07/13/2016 01:16 PM, Gunnar Morling wrote:
> Hi Scott,
>
> I had a short look at the tests you pointed to; in the one using BMT,
> why is it that the UserTransaction *and* the Neo4j TX API are used? I'd
> have expected it to be only one *or* the other?
With both container managed transactions and bean managed transactions
(BMT), a JTA transaction is in control of the transaction. With BMT,
UserTransaction is used by the application code to start/end the
transaction. In either case (BMT or CMT), the Neo4j TX API is controlled by
the JTA transaction.
If there isn't an active JTA transaction, the Ne04j TX API is in control of
the Neo4j transaction. With one caveat, that the Ne04j transaction should
be ended by the application code, before entering into a JTA transaction
(since it won't be joined into the JTA transaction).
Users can also disable the JTA transaction enlistment by using a NoSQL
profile with "transaction=none", instead of "transaction=1pc".
>
> In the one using CMT, there are also calls to the Neo4j TX API which
> apparently are ignored.
With CMT + BMT, the JTA transaction is in control, when the JTA transaction
ends, the Neo4j transaction ends as well and not before then. If the
application calls the Neo4j TX API, our TXProxy ignores calls to
TX.success/failure/close, other calls are passed through to the underlying
Neo4j Transaction object (e.g. run(String statement)), since that is where
the work actually occurs.
When the JTA transaction commits, the underlying Neo4j tx.success() +
tx.close() are called. If the JTA transaction rolls back, the underlying
Neo4j tx.failure() + tx.close() are called.
> What's the rationale behind that?
To enlist the Neo4j transaction into the JTA transaction via a one phase
wrapper.
> Wouldn't it
> make more sense to raise an exception, similar to when
> EntityManager#getTransaction() is invoked for a JTA entity manager?
If the NoSQL profile is JTA enabled, it should be enlisted into the JTA
transaction, allowing the application to control all of the database
operations that occur within the JTA transaction.
We also have the equivalent of JPA RESOURCE_LOCAL, via NoSQL profiles that
are not JTA enabled ("transaction=none" in the profile definition).
>
> In the CMT case, did you consider to inject the Neo4j Session instead of
> Driver into the bean, again akin to injection of JTA entity managers?
It is possible that we could also look at TransactionScoped injection of
sessions, but not sure yet. We started with (RequestScoped) Session
injection but commented that out [1] when we added JTA enlistment.
TransactionScoped injection of Sessions could be yet another way to write
CMT/BMT code.
>
> All in all, I'm wondering whether things couldn't be handled analogous
> to the usage of entity managers:
>
> * For a JTA-enabled NoSQL persistence unit, obtain the Session via
> injection (its lifecycle is controlled by the container and bound to the
> managed transaction), any manual interaction with the Neo4j TX API is
> forbidden, instead the container manages transactions or the user is
> (via UserTransaction)
> * For a non-JTA-enabled NoSQL persistence unit, obtain the Driver via
> injection, and the user is in charge of Session lifecycle and
> transaction control
Well, you haven't yet seen the above responses yet, I think the
TransactionScoped Session injection idea is good but also introduces a
different way to write CMT/BMT code for Ne04j. I disagree on making the
current (WF NoSQL/Ne04j TX enlistment) approach illegal, as I don't yet see
a problem with the current approach.
Are there difficulties with Hibernate OGM that you anticipate with either
approach of JTA TX enlistment for Neo4j?
>
> I hope that'd make sense for actually transactional stores such as
> Neo4j, for non-TX stores such as MongoDB thinks look different.
Agreed, for MongoDB, we treat that as "transaction=none", meaning no JTA
transaction enlistment for MongoDB.
>
> --Gunnar
>
Scott
[1]
https://github.com/scottmarlow/wildfly/blob/nosql-dev9/nosql/neo4j/src/ma...