users@jersey.java.net

Re: [Jersey] Resource Management through nested sub-locators

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Wed, 10 Jun 2009 13:21:14 +0200

Hi Martin,

We do seem to be going around in circles a bit :-)

I guess i am having a hard time understanding why in all cases the
commit or rollback has to be performed after the response has been
serialized. And, as you can tell i lack a certain experience in the
area :-)


On Jun 10, 2009, at 10:03 AM, Martin Probst wrote:

>> The 4xx set of errors are associated with an error related into the
>> [412] This response code allows the client to
>> place preconditions on the current resource metainformation (header
>> field data)
>> and thus prevent the requested method from being applied to a
>> resource other than
>> the one intended.
>>
>> Thus i do not think such status codes are appropriate to signal
>> rollback, or
>> for an appropriate response to send to the client if rollback
>> occurred.
>
> I don't agree. I can imagine a server side implementation accepting a
> request, performing some work, then checking the preconditions,
> detecting the precondition failure, and then using rollback to undo
> any changes performed. That's a really nice use case for transactions,
> if you can't do that, they won't be of much help.
>

Good point.

So for that case the application could do one of the following:

   1) return a 412, e.g. return Response.status(412).build().

   2) throw a WebApplicationException(412)

   3) or throw an exception that is mapped to 412.

in addition to a general case of:

   4) or thrown an exception that is unmapped and passed to the
container

The common factor, for the first three, is you want on a 412 status
code to perform rollback. In addition rollback should be performed for
4) and for the case of an exception thrown that is mapped to a 5xx
response.

I think you mentioned this before, but what if the application could
signal that a set of status codes from a resource method should result
in a rollback ?


>
>>> I would identify these cases:
>>> * regular response is created and returned by the application ==>
>>> commit
>>> * application throws a WebApplicationException ==> commit
>>
>> In the above two cases a 500 status might be returned.
>
> Yes.
>
>>> * application throws some sort of RuntimeException ==> call
>>> ExceptionMappers and have them indicate whether the request failed
>>>
>>
>> It seems to be that the existing approaches of signaling rollback
>> using an
>> exception do not really fit well with JAX-RS, and the use of a 5xx
>> status
>> code is the better way to signal a rollback.
>
> I don't agree. Requiring a 500 code if you want a rollback and "piggy
> backing" the information that a database rollback is required on top
> of the status code is in my opinion a really bad idea. This is a
> massive constraint as to when server side implementations may use
> rollback, or it will force people to use 500 codes in situations where
> they are really not appropriate, just to get the rollback.
>
> Remember that transaction rollbacks do not need to be the consequence
> of an internal server error. There are lots of cases where you happily
> code to expect some condition and use a rollback to compensate for
> earlier work. This is the key feature of a transactional database
> system.
>

OK.


>> Aside from using AOP the only other solution I can think of is what I
>> previously sent and it is to utilize a closure and define that any
>> exception
>> originating from the closure will result in rollback.
>
> The closure will not work as it would not include the entire request
> handling, but only the location step handling.
>

I was wondering if the closure could defer some aspect to later on.


> I might be a bit repetitive here, but the thing that would work would
> be allowing the user to install/inject some class that will always get
> notified if an unhandled exception occurred during request processing
> (and that should include writing the response). You could either have
> a dedicated "ExceptionListener" or extend the ExceptionMapper somehow,
> but the first one is probably cleaner. Is there anything that speaks
> against this?
>

I am still not sure that is sufficient for all the cases of how a
response can be returned.

However, do you propose that, given the pre-condition example above
that cases 2, 3, 4 should result in rollback, but not 1)?

I think we could have the following state on a response:

   a) for an exception mapped to a response we could set the response
state to stay
        MAPPED_EXCEPTION.

   b) for an umapped exception passed to the container, we could set
the response state
        to say UNMAPPED_EXCEPTION

   c) otherwise the state is DIRECT_RESPONSE

Then in the Closeable the response state could be checked.

Is that something that would work for you?

Paul.