|
YK 7 |
at Mar 19, 2012 at 9:31 pm
|
⇧ |
| |
Sorry, forget the two ServerRuntimes please.
Suppose that we have only one server runtime which is instantiated once
during all web application life cycle.
I took a look at the Cayenne's source code and found that Calling
serverRuntime.getDataDomain().createTransaction(), in my example, will
create an internal transaction: new InternalTransaction(delegate).
What I understand here is that the transaction is created against the
DataDomain AND IS NOT AWARE of the current user session.
Now, if I bound it to the current thread then if I call
transaction.commit(), will this commit all the changes of all the active
sessions (users)?
This is not of course the expected behavior, since I's like to commit only
the changes of a single user.
What I don't understand here is how Cayenne transaction will commit
independently the changes of a each user or HTTP session.
Hope my problem is clear now!
On Mon, Mar 19, 2012 at 3:37 PM, Andrus Adamchik wrote:Oh and if you are committing to 2 DBs in separate transactions, just
forget all these XA transactions, and just use Cayenne as normal, using
ObjectContext instances from an appropriate runtime.
Oh, just remember that a Cayenne TX is bound to the current execution
thread. So while ServerRuntime being a singleton is red herring, make sure
there's no TX overlap within a request thread, either because you have
manual transactions, or e.g. you have listeners that commit to another DB
within the first DB commit.
Andrus
On Mar 19, 2012, at 5:30 PM, Andrus Adamchik wrote:
Hi there,
This seems to be a duplicate of the earlier message. John gave a
completely correct answer about ServerRuntime and ObjectContext scoping.
Maybe I'm not correctly using Cayenne to manage transaction when we have
more than one server runtime. If so, what's the best way to achieve that
please?
If you have 2 runtimes accessing 2 independent databases, and want to
commit 2 contexts to those together, you can either commit them
independently (c1.commitChanges(); c2.commitChanges(); - they won't be a
part of the same transaction with all the consequences), or find a solution
for distributed transaction management (so called XA transactions). In the
later case you can check "External Transactions" in Cayenne, and let the
JEE container handle those.
I'd much prefer the former solution and the app dealing with
consequences, to much heavier XA transactions. But Cayenne would allow you
to use the later by absolving itself of TX handling responsibility and
letting you or your appserver to handle all that two-phase commit fun stuff.
Andrus
On Mar 19, 2012, at 5:10 PM, YK 7 wrote:
Andrus,
I'm new to Cayenne and I'm testing the Cayenne's transaction management
using the following scenario:
I have a simple web application that uses Spring to create
singletons(Services, DAOs...) and make the dependencies injection.
My example is using two different Databases (MySQL and Oracle) and
thus, I
have defined two Cayenne Server Runtimes:
One for Oracle and one for MySQL. Those two ServerRuntimes are
instantiated
once in a singleton.
I'm trying to use Cayenne Transactions using :
Transaction tx = serverRuntime.getDataDomain().createTransaction().
....
tx.commit(); //or tx.rollback() depending on the situation
The problem here is that if I do so, it means that if a user(or HTTP
session) changes are committed, all other users(or HTTP sessions)
changes
will also be committed.
This is because serverRuntime is a singleton and the transaction is
created
against it (and not against the objectContext which is bound to the HTTP
session).
I also took a look at the ServerRuntime source code and noticed that it
defines two instance properties (injector and modules which are in the
parent class: CayenneRuntime).
If I'm not mistaken, this means that ServerRuntime is not a good
candidate
to be defined as a singleton (one instance per application).
Maybe I'm not correctly using Cayenne to manage transaction when we have
more than one server runtime. If so, what's the best way to achieve that
please?
Thanks