users@jersey.java.net

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

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Tue, 09 Jun 2009 14:07:58 +0200

On Jun 9, 2009, at 12:37 PM, Martin Probst wrote:

>> The response is serialized to the servlet, then any per-request
>> resource
>> instances are destroyed and any Closeable instances are closed.
>>
>> Maybe it is sufficient for your application to detect if commit has
>> not been
>> called (i.e. the method did not finish) and if so rollback is
>> performed ?
>
> Yes, but which method did not finish,

Essentially the application did not return a Response, namely a
resource method did not finish (or was not called).


> and who then calls commit? If I
> want to use Jersey's web handling infrastructure, the Servlet.service
> method will finish, so my application code cannot know whether all
> went well or not. That is the problem.
>
> In the filter, I just do a
> try {
> chain.doFilter(request, response);
> commitSession();
> } finally {
> rollbackSession(); // no-op if already committed
> closeSession();
> }
>

I see.


> Ideally speaking, I would have a Closeable resource that will
> terminate the session no matter what, and commit if it's still open
> (the success case). The rolling back would then be done by the
> ExceptionListener I propose above, and that would need to be notified
> (to make things a bit more concrete) by WebApplicationImpl at the
> places before it invokes ExceptionMappers.
>
>> Another approach is to:
>>
>> 1) clearly define the HTTP status codes on which rollback must be
>> performed
>> if a commit has not already occurred;
>>
>> 2) define a mode in JAX-RS/Jersey that never passes exception to
>> servlet.
>>
>> I think the latter fits better in the style of JAX-RS i.e. key
>> things of the
>> HTTP status code.
>
> So then I'd have a servlet filter that checks after filtering if the
> status code is e.g. == 500, and then rolls back, otherwise commits.
>

Yes.


> That is probably reasonable, but I think I'll run into cases where
> status codes are not sufficient to describe the error behaviour. I can
> imagine cases where user code would want a transaction to commit, even
> if it was e.g. a malformed request, and other cases where I wouldn't
> want that.
>

A malformed request should return a 400 status code.

For the example you give i am guessing you are referring to some form
of side-effect not related to the resource state, and that a 400 is
returned before any resource state is modified. And, if there is an
error with creating the side-effect state a 500 response should be
returned and rollback should be performed


BTW I found the following here on Servlet and transactions:

http://java.sun.com/blueprints/guidelines/designing_enterprise_applications_2e/transactions/transactions6.html

   A servlet or JSP page may start a transaction only in its service
method. A transaction
   that is started by a servlet or JSP page must be completed before
the service method
   returns; in other words, transactions may not span Web requests. If
the service method
   returns with a pending UserTransaction (that is, begin has been
called, but not commit
   or rollback), the container aborts the transaction and rolls back
all data updates. JTA
   transactions are not supported in servlet filters and Web
application event listeners.


I am not sure how things work when a servlet invokes an session bean
method for container managed transactions, or when the session bean
method does not finish and a transaction is still open.


> Whether you commit or roll back is IMHO a service implementation
> detail that does not have a natural mapping to status codes, or at
> least doesn't need to have one and shouldn't be forced to have one.
>

But it makes it so much easier if that is the case :-)

In any case this is complex!
Paul.