Return-Path: Delivered-To: apmail-cayenne-dev-archive@www.apache.org Received: (qmail 36849 invoked from network); 1 Dec 2009 13:57:00 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 1 Dec 2009 13:57:00 -0000 Received: (qmail 90093 invoked by uid 500); 1 Dec 2009 13:57:00 -0000 Delivered-To: apmail-cayenne-dev-archive@cayenne.apache.org Received: (qmail 90075 invoked by uid 500); 1 Dec 2009 13:57:00 -0000 Mailing-List: contact dev-help@cayenne.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cayenne.apache.org Delivered-To: mailing list dev@cayenne.apache.org Received: (qmail 90065 invoked by uid 99); 1 Dec 2009 13:57:00 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 01 Dec 2009 13:57:00 +0000 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: local policy) Received: from [208.78.103.231] (HELO vorsha.objectstyle.org) (208.78.103.231) by apache.org (qpsmtpd/0.29) with SMTP; Tue, 01 Dec 2009 13:56:51 +0000 Received: (qmail 16470 invoked from network); 1 Dec 2009 13:56:30 -0000 Received: from unknown (HELO ?IPv6:::1?) (127.0.0.1) by localhost with SMTP; 1 Dec 2009 13:56:30 -0000 Message-Id: From: Andrus Adamchik To: dev@cayenne.apache.org In-Reply-To: <9f90c2b60912010541h70242988y5937ebe74ca8a292@mail.gmail.com> Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit Mime-Version: 1.0 (Apple Message framework v936) Subject: Re: Singletons in Cayenne and problems. Can I use multiple transactions? Date: Tue, 1 Dec 2009 15:56:29 +0200 References: <9f90c2b60912010444j716ae91cu61bf29e382922047@mail.gmail.com> <24928454-C18A-49A9-B732-16EB18E2BBD2@objectstyle.org> <9f90c2b60912010527v6186ea6fre3d1e9a5c2a67324@mail.gmail.com> <9f90c2b60912010541h70242988y5937ebe74ca8a292@mail.gmail.com> X-Mailer: Apple Mail (2.936) X-Virus-Checked: Checked by ClamAV on apache.org Calling Cayenne transactions "singletons" is not really accurate, as they are thread-local and scoped, and you can control that scope if you have to. So here is how you can address your problem - unbind outer transaction from the thread when the nested transaction is started, and then rebind it back after inner commit/rollback: Transaction outer = Transaction.getThreadTransaction(); try { Transaction inner = ... // create Transaction.bindThreadTransaction(inner); ... // do work } finally { Transaction.bindThreadTransaction(outer); } I am undecided on whether DataDomain-scoped transactions is a good idea going forward. This goes against most J2EE users expectations about transactions, and while addressing one use case it breaks others (i.e. other users may need a single commit point across multiple DataDomains). Andrus On Dec 1, 2009, at 3:41 PM, Evgeny Ryabitskiy wrote: > Manual? I create them manually by calling domain1.createTransaction() > and domain2.createTransaction(). > > How it happen: One method from Module 1 do some queries (first domain) > then call method from Module 2 that is also doing some queries (second > domain), after method from module 2 finished: method from module 1 is > doing more queries. > > So it's like an "nested" transaction (from mod 2) but is performed on > another DataDomain (it's another DB server) and absolutely isolated > from huge "outer" transaction (mod 1). > But I want to control both! and separately... > > Evgeny. > > > > 2009/12/1 Andrus Adamchik : >> Are those manual transactions? (I.e. how does it happen that >> transaction >> scopes overlap between two queries?) >> >> Also you can reuse the current thread transaction between multiple >> domains. >> As I said, connections are scoped by DataNode name, so the same >> transaction >> will return 2 separate connections for 2 queries run against 2 >> different >> nodes. >> >> Andrus >> >> On Dec 1, 2009, at 3:27 PM, Evgeny Ryabitskiy wrote: >> >>> Problem in multiple Domains. >>> When I am creating transaction I am creating it's for specific >>> DataDomain (like a DataContext). >>> When I have 2 Modules with dedicated DataDomains (so it will be 2 >>> DataDomains) I can create 2 Transactions >>> (domain.createTransaction()). >>> >>> But to thread I can bind only one. Then when I start performing >>> queries I >>> got: >>> 1)First Domain Transaction is binded and handled normally >>> 2)Second Domain Transaction is override by first DataDomain. So >>> when I >>> perform query for second: ThreadLocals return Transaction for firs >>> Domain. >>> >>> Evgeny >>> >>> >>> >>> 2009/12/1 Andrus Adamchik : >>>> >>>> Singletons are bad in a general purpose framework, like Cayenne. No >>>> question >>>> about that. Per your description even thread-local singletons can >>>> be a >>>> problem, which is less obvious to me, but I guess real in some >>>> circumstances. So let's see what those are. >>>> >>>>> 2)DataContext.getThreadLocal() >>>>> Solved by own ThreadLocal for each module. (modules can work in >>>>> one >>>>> thread) >>>>> //also spend some time >>>> >>>> This is just a convenience in Cayenne. Nobody's forced to use it. >>>> I will >>>> go >>>> as far as to suggest to remove it from Cayenne 3.1 as a built-in >>>> feature, >>>> and just document it as a possible design pattern in a user >>>> application. >>>> >>>>> 3)Transaction.getThreadTransaction() >>>>> this is killing one!!! >>>>> using of own ThreadLocal doesn't help. >>>>> It's hard-coded in performing Query to use this singleton >>>>> Transaction.getThreadTransaction() >>>>> And that is really huge problem for me. >>>> >>>> J2EE pattern of tying a transaction to an execution thread, even if >>>> multiple >>>> data sources are involved, makes sense as it allows to commit/ >>>> rollback >>>> multiple things at once. Cayenne Transaction sort of follows >>>> that. JDBC >>>> connections within the transaction are scoped by DataNode name. >>>> So what >>>> exactly is the problem? >>>> >>>> Andrus >>>> >>>> >>>> >>>> On Dec 1, 2009, at 2:44 PM, Evgeny Ryabitskiy wrote: >>>> >>>>> Hello 2 everyone! >>>>> >>>>> Today I one more time thinking about singleton pattern and it's >>>>> hard >>>>> usssage in Cayenne. >>>>> >>>>> So.. I have several modules, each has own DomainConfig file and >>>>> connection to it's DataBase. Sometimes there can be used >>>>> different DB >>>>> servers and even different DB types (usually it's Oracle and MS >>>>> SQL, >>>>> sometimes Sybase). >>>>> >>>>> Singletons: >>>>> 1) Configuration.getSharedConfiguration() >>>>> This problem is solved: >>>>> DefaultConfiguration conf = new >>>>> DefaultConfiguration("module1-cayenne.xml"); >>>>> conf .initialize; >>>>> conf.getDomain(); >>>>> //spend some time to find solution... everywhere examples with >>>>> SharedConfiguration >>>>> >>>>> 2)DataContext.getThreadLocal() >>>>> Solved by own ThreadLocal for each module. (modules can work in >>>>> one >>>>> thread) >>>>> //also spend some time >>>>> >>>>> 3)Transaction.getThreadTransaction() >>>>> this is killing one!!! >>>>> using of own ThreadLocal doesn't help. >>>>> It's hard-coded in performing Query to use this singleton >>>>> Transaction.getThreadTransaction() >>>>> And that is really huge problem for me. >>>>> >>>>> So me suggestion is to move this ThreadLocal to DataDomain. >>>>> Still can >>>>> use singleton API for standalone applications. >>>>> Also we can move DataContext to DataDomain. >>>>> >>>>> Evgeny. >>>>> >>>> >>>> >>> >> >> >