FAQ
Hi,

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.

The ObjectContexts are instantiated once per HTTP session and sent to the
DAOs via ThreadLocal (This is very similar to the Cayenne's HTTP filter).
Everything works well if I use directly objectContext.commitChanges()
method to commit changes to DB.

What I'm trying to do next is 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

Search Discussions

  • John Huss at Mar 17, 2012 at 1:54 pm
    ServerRuntime should be a singleton, that is correct.

    ObjectContexts are dependent of each other (unless explicitly nested) so
    committing one will one commit the changes in THAT context, not the changes
    for other users if you are creating separate contexts for each user.

    This is because Cayenne does not start a transaction or issue any INSERT,
    UPDATE, DELETE SQL statements until you call commitChanges. All
    modifications are performed in memory only until you commit. When you
    commit an ObjectContext, it generates the SQL statements only for the
    modifications it contains and executes them in a transaction. So the
    contexts are independent.

    Are your two databases using the same schema or different (complementary)
    schema?
    On Sat, Mar 17, 2012 at 3:16 AM, YK 7 wrote:

    Hi,

    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.

    The ObjectContexts are instantiated once per HTTP session and sent to the
    DAOs via ThreadLocal (This is very similar to the Cayenne's HTTP filter).
    Everything works well if I use directly objectContext.commitChanges()
    method to commit changes to DB.

    What I'm trying to do next is 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
  • YK 7 at Mar 17, 2012 at 8:41 pm
    1. I already tested object context commitChanges method without any problem.

    2. I'm using two DIFFERENT databases: Oracle and MySQL.
    Actually, I'm using a schema for Oracle and a catalog for MySQL.
    Please, note that there entities of the tow DBs are completely independent.

    On Sat, Mar 17, 2012 at 2:54 PM, John Huss wrote:

    ServerRuntime should be a singleton, that is correct.

    ObjectContexts are dependent of each other (unless explicitly nested) so
    committing one will one commit the changes in THAT context, not the changes
    for other users if you are creating separate contexts for each user.

    This is because Cayenne does not start a transaction or issue any INSERT,
    UPDATE, DELETE SQL statements until you call commitChanges. All
    modifications are performed in memory only until you commit. When you
    commit an ObjectContext, it generates the SQL statements only for the
    modifications it contains and executes them in a transaction. So the
    contexts are independent.

    Are your two databases using the same schema or different (complementary)
    schema?
    On Sat, Mar 17, 2012 at 3:16 AM, YK 7 wrote:

    Hi,

    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.

    The ObjectContexts are instantiated once per HTTP session and sent to the
    DAOs via ThreadLocal (This is very similar to the Cayenne's HTTP filter).
    Everything works well if I use directly objectContext.commitChanges()
    method to commit changes to DB.

    What I'm trying to do next is 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

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupuser @
categoriescayenne
postedMar 17, '12 at 8:17a
activeMar 17, '12 at 8:41p
posts3
users2
websitecayenne.apache.org

2 users in discussion

YK 7: 2 posts John Huss: 1 post

People

Translate

site design / logo © 2022 Grokbase