vipx / google-guice

Automatically exported from code.google.com/p/google-guice
Apache License 2.0
0 stars 0 forks source link

Add @UnitOfWork annotation #731

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Something that seems to be missing from guice-persist is a @UnitOfWork 
equivalent to the @Transactional annotation. One that will automatically 
start/stop a UnitOfWork as required, but not begin/commit a transaction.

Our use case: we have a bunch of classes that are used for database access. We 
use these in command-line applications, both during initialisation (in provider 
methods) and at run-time.

If a method exists for altering data in the database, we can happily apply 
@Transactional to it. It can now be safely called whether you're in an active 
UnitOfWork or not (because @Transactional will only start/stop a UnitOfWork if 
required).

For methods that only read data from the database, we don't want to 
start/commit transactions needlessly, so the @Transactional tag is a no-go. But 
- we have no means of guaranteeing that a method is encapsulated by a 
UnitOfWork automatically... there's no way to check if a UnitOfWork is already 
running, so there's no way to start/stop one only as required.

Would be a boon to have this functionality. Alternatively, an "isRunning()" 
method on UnitOfWork would make it possible for us (and others) to create our 
own automatic UnitOfWork controllers.

Original issue reported on code.google.com by spootsy....@gmail.com on 5 Oct 2012 at 4:28

GoogleCodeExporter commented 9 years ago
Patch attached to issue 730 which addresses this. 

It doesn't expose the isWorking method, but rather introduces an 
invocation-counting mechanism to JpaPersistService so that begin()/end() calls 
can be nested safely.

Original comment by spootsy....@gmail.com on 10 Oct 2012 at 11:46

GoogleCodeExporter commented 9 years ago
I haven't used the @UnitOfWork part of this patch, but I don't think the fix in 
JpaPersistService where it increments and decrements the count is working 
correctly.

I thrashed the service with soapUI using a load test on several service(all 
using PersistFilter) in my app simultaneously. I'm not sure how, since it's a 
ThreadLocal variable, but that count quickly get out of whack. As a result not 
all entity managers are getting closed and the connection pool eventually runs 
out of connections. Works fine with one thread.

Perhaps it's not handling nested @Transactions correctly. I wasted a lot of 
time trying get this patch working.

Original comment by julian.w...@gmail.com on 25 Jul 2013 at 3:22

GoogleCodeExporter commented 9 years ago
Hi @julian,

Thanks for trying out the patch. Sorry to hear you had problems with it.

Having had a look at the patch with fresh eyes, you hit the nail on the head. 
Nested transactions call "unitOfWork.begin()", but not "unitOfWork.end()", 
which would cause the problem you saw.

I'll post an updated patch when I get a chance. I've searched for any other 
possible mismatched begin/end calls, but that's the only one.

It should be an easy fix if you want to do it yourself. In 
JpaLocalTxnInterceptor, just add a try/finally block around line 56, so it 
becomes:

try {
  return methodInvocation.proceed();
} finally {
  unitOfWork.end();
}

Hope that helps some :)

Original comment by spootsy....@gmail.com on 30 Jul 2013 at 1:53

GoogleCodeExporter commented 9 years ago

Original comment by sberlin on 20 Dec 2013 at 2:16