users@jersey.java.net

Re: [Jersey] transaction-per-request

From: Adam Rabung <adamrabung_at_gmail.com>
Date: Mon, 19 Apr 2010 10:00:20 -0400

Hi,
Those two problems are significant, but I'm mapping all exceptions,
and currently don't implement any other Jersey filters. Not ideal,
but it seems like this approach will for me, for now. I will also
ensure the transaction is closed using a container filter.

Thanks, as always, for the quick and thorough responses!
Adam

On Mon, Apr 19, 2010 at 4:50 AM, Paul Sandoz <Paul.Sandoz_at_sun.com> wrote:
> HI Adam,
>
> The problem with using a ContainerResponseFilter to commit or roll back is
> that the response filter is not guaranteed to get called in the following
> circumstances:
>
> 1) if the resource throws an exception that is not mapped.
>     The exception will get passed through to the container and response
> filters will not be called.
>
> 2) a filter declared before TransactionManagementFilter throws an exception.
>    This breaks the filter chain:
>
>  https://jersey.dev.java.net/nonav/apidocs/latest/jersey/com/sun/jersey/api/container/filter/package-summary.html
>
> I am not sure if that is what you intended or not.
>
> If you are not interesting in supporting the mapping of exceptions to error
> pages then you can map say Throwable to a 500 response, this will catch
> anything that would otherwise be destined for the container. Then you can do
> the commit or rollback in the Closeable
>
> Paul.
>
>
>
> On Apr 16, 2010, at 8:37 PM, Adam Rabung wrote:
>
>> Aha, I think getMappedThrowable was the missing piece of the puzzle
>> for me.  Like Martin, I want to be able to rollback on exception.
>> Does this code look like a good start to you?  My transactions are
>> thread-local, and managed via these static methods...
>>
>> package mdt.web.jersey;
>>
>> import java.io.Closeable;
>> import java.io.IOException;
>>
>> import javax.ws.rs.core.Context;
>>
>> import mdt.core.Transaction;
>>
>> import com.sun.jersey.spi.CloseableService;
>> import com.sun.jersey.spi.container.ContainerRequest;
>> import com.sun.jersey.spi.container.ContainerRequestFilter;
>> import com.sun.jersey.spi.container.ContainerResponse;
>> import com.sun.jersey.spi.container.ContainerResponseFilter;
>>
>> public class TransactionManagementFilter implements
>> ContainerResponseFilter, ContainerRequestFilter {
>>        private CloseableService _closeableService;
>>
>>        public TransactionManagementFilter(@Context CloseableService cs) {
>>                _closeableService = cs;
>>        }
>>
>>        public ContainerRequest filter(ContainerRequest req) {
>>                Transaction.start();
>>                _closeableService.add(new TransactionReference());
>>                return req;
>>        }
>>
>>        public ContainerResponse filter(ContainerRequest req,
>> ContainerResponse response) {
>>                if (response.getMappedThrowable() == null) {
>>                        Transaction.commit();
>>                }
>>                else {
>>                        Transaction.rollback();
>>                }
>>                return response;
>>        }
>>
>>        public static class TransactionReference implements Closeable {
>>                public void close() throws IOException {
>>                        Transaction.ensureTransactionClosed();
>>                }
>>        }
>> }
>>
>>
>> On Fri, Apr 16, 2010 at 9:53 AM, Paul Sandoz <Paul.Sandoz_at_sun.com> wrote:
>>>
>>> HI Adam,
>>>
>>> To be honest i cannot recall all that discussion :-) need to go through
>>> it
>>> again.
>>>
>>> Filters are not appropriate to perform rolllback because the chain can be
>>> bypassed or broken by the throwing of an exception. But a request filter
>>> could add a Closeable that is guaranteed to get called. IIRC Martin had a
>>> particular requirement related to throwing of exceptions and rollback. It
>>> is
>>> now possible to obtain the mapped exception from ContainerResponse:
>>>
>>>
>>> https://jersey.dev.java.net/nonav/apidocs/latest/jersey/com/sun/jersey/spi/container/ContainerResponse.html#getMappedThrowable%28%29
>>>
>>> but i do not know if that satisfies his needs.
>>>
>>>
>>> To help me get up to speed can you tell me what your ideal solution might
>>> look like and using CloseableService does not work for you?
>>>
>>> Paul.
>>>
>>> On Apr 15, 2010, at 7:08 PM, Adam Rabung wrote:
>>>
>>>> Hello,
>>>> I am trying to cleanly implement "transaction-per-request" alongside
>>>> Jersey Resources.  That is, I'd like no mention of transactions in
>>>> individual resources, but rather in a central place, as outlined by
>>>> Martin Probst in an earlier email [1]:
>>>>
>>>> try {
>>>>  chain.doFilter(request, response);
>>>>  commitSession();
>>>> } finally {
>>>>  rollbackSession(); // no-op if already committed
>>>>  closeSession();
>>>> }
>>>>
>>>> I've seen a few conversations about this topic on the mailing list,
>>>> but I can't piece together a good solution using the advice.  I'd
>>>> rather avoid Spring for tx management, as it's not yet a dependency.
>>>> I've taken a look at CloseableService, ResourceFilter, overriding
>>>> ServletContainer.service, etc, and cannot see how I can use these to
>>>> implement transparent rollback-on-exception.  I got it working by
>>>> calling rollback in a custom ExceptionMapper, but that feels very
>>>> dirty :)
>>>>
>>>> If anyone has pulled this off, could they offer some pseudocode
>>>> describing the approach?  Extra bonus points if the solution gives me
>>>> metadata on what resource is being executed :)
>>>>
>>>> Thank you,
>>>> Adam
>>>>
>>>> [1] http://markmail.org/thread/aefgmci6r2thkqxc
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>>
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>
>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>
>