In my opinion, it's currently unnecessarily difficult to integrate basic transaction management with GWT-RPC.
Usually, in a web application it's best to start a transaction, when a call arrives at the server, and to commit it, when the server has finished processing and created the response. For GWT-RPC, this would mean to wrap all service methods with transaction handling code. Of course, it's possible to write each method like public String greetServer(final String input) throws IllegalArgumentException { beginTx(); try { String result = doGreetServer(input); commit(); } catch (Throwable t) { rollback(); throw t; } } But you definitely want to eliminate that boilerplate. So you can override RemoteServiceServlet's processCall() method. But look at the code: public String processCall(String payload) throws SerializationException { // First, check for possible XSRF situation checkPermutationStrongName(); try { RPCRequest rpcRequest = RPC.decodeRequest(payload, delegate.getClass(), this); onAfterRequestDeserialized(rpcRequest); return RPC.invokeAndEncodeResponse(delegate, rpcRequest.getMethod(), rpcRequest.getParameters(), rpcRequest.getSerializationPolicy(), rpcRequest.getFlags()); } catch (IncompatibleRemoteServiceException ex) { log( "An IncompatibleRemoteServiceException was thrown while processing this call.", ex); return RPC.encodeResponseForFailure(null, ex); } catch (RpcTokenException tokenException) { log("An RpcTokenException was thrown while processing this call.", tokenException); return RPC.encodeResponseForFailure(null, tokenException); } } The straightforward way would be to override it like public String processCall(String payload) throws SerializationException { beginTx(); try { super.processCall(payload); commit(); } catch (Throwable t) { rollback(); /* Optionally perform additional logging etc. here */ throw t; } } But that doesn't work reliably, because IncompatibleRemoteServiceException and RpcTokenException will escape, i.e. they won't reach the rollback(). >From the Javadoc of java.sql.Connection.close(): It is <b>strongly recommended</b> that an application explicitly commits or > rolls back an active transaction prior to calling the <code>close</code> > method. If the <code>close</code> method is called and there is an active > transaction, the results are implementation-defined. So all that can be currently done is copying and pasting the entire processCall() method to a subclass, replacing "delegate" (unfortunately private) with "this" (a hack!), and adding the transaction handling code there. Other options are of course using a dispatch approach like gwt-dispatch <http://code.google.com/p/gwt-dispatch/>, or maybe AOP - but this is not always desirable. What I would recommend is simply changing processCall() to: public String processCall(final String payload) throws SerializationException { // First, check for possible XSRF situation checkPermutationStrongName(); try { final RPCRequest rpcRequest = RPC.decodeRequest(payload, delegate.getClass(), this); return doProcessCall(rpcRequest); } catch (final IncompatibleRemoteServiceException ex) { log( "An IncompatibleRemoteServiceException was thrown while processing this call.", ex); onAfterRequestDeserialized(rpcRequest); return RPC.encodeResponseForFailure(null, ex); } catch (final RpcTokenException tokenException) { log("An RpcTokenException was thrown while processing this call.", tokenException); return RPC.encodeResponseForFailure(null, tokenException); } } protected String doProcessCall(final RPCRequest rpcRequest) throws SerializationException { return RPC.invokeAndEncodeResponse(delegate, rpcRequest.getMethod(), rpcRequest.getParameters(), rpcRequest.getSerializationPolicy(), rpcRequest.getFlags()); } Then, it's easy for everyone to override doProcessCall like: public String doProcessCall(RPCRequest rpcRequest) throws SerializationException { beginTx(); try { super.doProcessCall(rpcRequest); commit(); } catch (Throwable t) { rollback(); /* Optionally perform additional logging etc. here */ throw t; } } This would be a very simple change, and it would allow to do all kinds of things at the beginning and end of each service method, as well as handling/logging top level Exceptions in a central place. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors