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.