You can annotate a method with @Transactional(propagation=REQUIRES_NEW). I
don't know whether this is supported on all databases, or whether there are
any other pitfalls in practice.

-Darius

On Mon, Feb 27, 2012 at 8:45 AM, Burke Mamlin <[email protected]>wrote:

> Can we devise a convention/recipe for cleanly creating a separate writable
> transaction within a read-only transaction?  If someone wants/needs to
> create some side effects inside a read-only transaction, it would be nice
> to have a common convention for how to implement such a side effect (e.g.,
> either appropriate annotations and/or a utility method).
>
> For example, a service provides a transactionless or read-only transaction
> around a method and some process introduced by a module during that method
> wants to write something to the database on the side.  Is there a way for
> the module to create it's own separate transaction to perform the side
> effect without forcing the service method to create a transaction?
>
> -Burke
>
>
> On Mon, Feb 27, 2012 at 9:59 AM, Ben Wolfe <[email protected]> wrote:
>
>> @Transactional(readOnly=true, propagation=Propagation.SUPPORTS) looks
>> like the best solution.
>>
>> Dissecting that suggestion according to the article:
>>
>> *@Transactional* so that hibernate is happen and has its endpoints
>> *readOnly=true* so that a database write doesn't occur
>> *Propogation.SUPPORTS* so that the transaction is never really started
>> unless asked for
>>
>> Did you confirm this still works with hibernate? (validating my first
>> assumption above about @Transactional?)
>>
>> All read/write methods will need
>> @Transaction(propogration=Propogration.REQUIRED)
>>
>> Ben
>>
>>
>> On Sun, Feb 26, 2012 at 7:22 AM, Rafal Korytkowski <[email protected]>wrote:
>>
>>> I'd vote to put @Transactional(readOnly=true,
>>> propagation=Propagation.SUPPORTS) at the class level of service layer impls
>>> and fine tune methods that aren't read only.
>>>
>>> Propagation.SUPPORTS allows to eliminate the transaction overhead that
>>> Darius is hoping to achieve with the DAO example in a more general and
>>> nicer way. More info here [0].
>>>
>>> There's not much difference between having transactional DAOs and
>>> Services. The latter is more widely used for the reason I gave, but it's a
>>> matter of taste.
>>>
>>> -Rafal
>>>
>>> [0] - http://www.ibm.com/developerworks/java/library/j-ts1/index.html
>>>
>>>
>>> On 24 February 2012 22:00, Darius Jazayeri <[email protected]>wrote:
>>>
>>>> Spring tries to use the existing transaction unless you say
>>>> @Transactional(propagation=Propagation.REQUIRES_NEW).
>>>>
>>>> I would *love* to get rid of the @Transactional annotations on our
>>>> services, and just put annotations on the methods that actually require
>>>> them.
>>>>
>>>> -Darius
>>>>
>>>>
>>>> On Fri, Feb 24, 2012 at 12:32 PM, Ben Wolfe <[email protected]> wrote:
>>>>
>>>>> FYI, here is the relevant ticket:
>>>>> https://tickets.openmrs.org/browse/TRUNK-208
>>>>>
>>>>> I could live with it on the DAO if we also examine all serviceimpls
>>>>> for multiple calls to the DAO layer and add the annotation to the impl if
>>>>> it does more than one.
>>>>>
>>>>> Can we do away with the generic @Transactional on the class and force
>>>>> devs to add @Transactional on methods that need it?  This should remove 
>>>>> the
>>>>> need for @Transactional(readOnly=true) and limit the number of times its
>>>>> forgotten.  Alternatively, we make the class level annotation 
>>>>> readOnly=true.
>>>>>
>>>>> Are we also sure that if a transaction is started at the service layer
>>>>> that the DAO layer is using that same one instead of starting a new one?
>>>>>
>>>>> Ben
>>>>>
>>>>>
>>>>> On Fri, Feb 24, 2012 at 3:13 PM, Darius Jazayeri <
>>>>> [email protected]> wrote:
>>>>>
>>>>>> The reason I'd rather have them in the HibernateDAO is so we can
>>>>>> write a service method like this, without paying the transactional 
>>>>>> penalty:
>>>>>>
>>>>>> public MySettings getSettings() {
>>>>>>     if (cached == null) {
>>>>>>         cached = dao.getSettings(); // this method has an
>>>>>> @Transactional annotation
>>>>>>     }
>>>>>>     return cached;
>>>>>> }
>>>>>>
>>>>>> Basically I'm saying that the transactional annotation should be put
>>>>>> in the concrete DAO only where we actually hit a transactional datastore.
>>>>>>
>>>>>> If we're putting the annotations in the ServiceImpl I'd need to do
>>>>>> something like this:
>>>>>>
>>>>>> public MySettings getSettings() {
>>>>>>     if (cached == null) {
>>>>>>         cached = getSettingsFromDao();
>>>>>>     }
>>>>>>     return cached;
>>>>>> }
>>>>>>
>>>>>> @Transactional(readOnly=true)
>>>>>> private MySettings getSettingsFromDao() {
>>>>>>     return dao.getSettings();
>>>>>> }
>>>>>>
>>>>>> It's not the end of the world to have to do that, but is there any
>>>>>> theoretical justification or best-practice recommendation that says we
>>>>>> should put annotations in the service layer when we believe that we're
>>>>>> calling a transactional DAO, rather than in the DAO layer when we know 
>>>>>> for
>>>>>> sure we're hitting the datastore?
>>>>>>
>>>>>> -Darius
>>>>>>
>>>>>> PS- Definitely if a ServiceImpl or a Controller method is going to
>>>>>> make multiple Service or DAO calls, it should explicitly mark the
>>>>>> transaction itself. But that's independent.
>>>>>>
>>>>>>
>>>>>> On Fri, Feb 24, 2012 at 10:08 AM, Ben Wolfe <[email protected]> wrote:
>>>>>>
>>>>>>> Yes, lets move these to the ServiceImpl.  Do we have a ticket
>>>>>>> somewhere to move the rest of our transaction annotations from 
>>>>>>> interface to
>>>>>>> impl?
>>>>>>>
>>>>>>> Ben
>>>>>>>
>>>>>>>
>>>>>>> On Fri, Feb 24, 2012 at 9:55 AM, Wyclif Luyima 
>>>>>>> <[email protected]>wrote:
>>>>>>>
>>>>>>>> @Rafal, i agree with what you are saying, so we should move them
>>>>>>>> from HibernateVisitDao to VisitServiceImpl?
>>>>>>>>
>>>>>>>> Wyclif
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> On Fri, Feb 24, 2012 at 5:15 AM, Rafal Korytkowski <
>>>>>>>> [email protected]> wrote:
>>>>>>>>
>>>>>>>>> I've found a way to have the advice around @Transactional so we
>>>>>>>>> don't need to change anything in Visits.
>>>>>>>>>
>>>>>>>>> Anyway, I don't think we should move @Transactional to the DAO
>>>>>>>>> layer. In general it's the service layer that defines units of work 
>>>>>>>>> that
>>>>>>>>> should be transactional. If you have multiple calls to DAO in a 
>>>>>>>>> service
>>>>>>>>> method, you will want to have @Transactional in the service method 
>>>>>>>>> anyway.
>>>>>>>>>
>>>>>>>>> -Rafal
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On 24 February 2012 03:11, Darius Jazayeri <[email protected]>wrote:
>>>>>>>>>
>>>>>>>>>> Moving this to the dev list.
>>>>>>>>>>
>>>>>>>>>> Wyclif, I assume that you mean from HibernateVisitDAO to
>>>>>>>>>> VisitServiceImpl...
>>>>>>>>>>
>>>>>>>>>> So, in the long run, we need to move the transactional
>>>>>>>>>> annotations off of the service interface. I'd argue that they should 
>>>>>>>>>> go to
>>>>>>>>>> the concrete DAO, and only on the methods that actually hit the 
>>>>>>>>>> database.
>>>>>>>>>> The alternative would be to move them to the ServiceImpl.
>>>>>>>>>>
>>>>>>>>>> That said, I'm fine if we want to move them from
>>>>>>>>>> HibernateVisitDAO up to the VisitService *interface* for
>>>>>>>>>> consistency, so that we can refactor *all* our services later.
>>>>>>>>>> But what's the argument for moving it from the HibernateDAO to the
>>>>>>>>>> ServiceImpl?
>>>>>>>>>>
>>>>>>>>>> Ideally Rafal will quickly figure out how to move the recent
>>>>>>>>>> advice code he wrote so it's triggered by any @Transactional method
>>>>>>>>>> anywhere, and this will be moot.
>>>>>>>>>>
>>>>>>>>>> -Darius
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On Thu, Feb 23, 2012 at 5:58 PM, Wyclif Luyima <
>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>
>>>>>>>>>>> Hi guys,
>>>>>>>>>>>
>>>>>>>>>>> @Daniel, we need to move the @Transanctional annotations from
>>>>>>>>>>> HibernateVisitDao to ConceptServiceImpl before cutting the 1.9 RC
>>>>>>>>>>>
>>>>>>>>>>> Wyclif
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>> ------------------------------
>>>>>>>>>> Click here to 
>>>>>>>>>> unsubscribe<[email protected]?body=SIGNOFF%20openmrs-devel-l>from
>>>>>>>>>>  OpenMRS Developers' mailing list
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> ------------------------------
>>>>>>>>> Click here to 
>>>>>>>>> unsubscribe<[email protected]?body=SIGNOFF%20openmrs-devel-l>from
>>>>>>>>>  OpenMRS Developers' mailing list
>>>>>>>>>
>>>>>>>>
>>>>>>>> ------------------------------
>>>>>>>> Click here to 
>>>>>>>> unsubscribe<[email protected]?body=SIGNOFF%20openmrs-devel-l>from
>>>>>>>>  OpenMRS Developers' mailing list
>>>>>>>>
>>>>>>>
>>>>>>> ------------------------------
>>>>>>> Click here to 
>>>>>>> unsubscribe<[email protected]?body=SIGNOFF%20openmrs-devel-l>from
>>>>>>>  OpenMRS Developers' mailing list
>>>>>>>
>>>>>>
>>>>>> ------------------------------
>>>>>> Click here to 
>>>>>> unsubscribe<[email protected]?body=SIGNOFF%20openmrs-devel-l>from
>>>>>>  OpenMRS Developers' mailing list
>>>>>>
>>>>>
>>>>> ------------------------------
>>>>> Click here to 
>>>>> unsubscribe<[email protected]?body=SIGNOFF%20openmrs-devel-l>from
>>>>>  OpenMRS Developers' mailing list
>>>>>
>>>>
>>>> ------------------------------
>>>> Click here to 
>>>> unsubscribe<[email protected]?body=SIGNOFF%20openmrs-devel-l>from
>>>>  OpenMRS Developers' mailing list
>>>>
>>>
>>> ------------------------------
>>> Click here to 
>>> unsubscribe<[email protected]?body=SIGNOFF%20openmrs-devel-l>from 
>>> OpenMRS Developers' mailing list
>>>
>>
>> ------------------------------
>> Click here to 
>> unsubscribe<[email protected]?body=SIGNOFF%20openmrs-devel-l>from 
>> OpenMRS Developers' mailing list
>>
>
> ------------------------------
> Click here to 
> unsubscribe<[email protected]?body=SIGNOFF%20openmrs-devel-l>from 
> OpenMRS Developers' mailing list
>

_________________________________________

To unsubscribe from OpenMRS Developers' mailing list, send an e-mail to 
[email protected] with "SIGNOFF openmrs-devel-l" in the  body (not 
the subject) of your e-mail.

[mailto:[email protected]?body=SIGNOFF%20openmrs-devel-l]

Reply via email to