users@jersey.java.net

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

From: Martin Probst <mail_at_martin-probst.com>
Date: Tue, 9 Jun 2009 12:37:42 +0200

> 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, 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();
}

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.

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.

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.

Martin