Have spent couple of hours to make Spring TransactionInterceptor work
properly with @Transactional annotation in the way it is described in
Spring documentation. H.e. to support both class and method
annotations.
The main problem I've met was with
AnnotationTransactionAttributeSource class which always provides class-
level transaction attributes but not the one I've specified for my
method. It worked only if there were no class @Transactional
annotation. And the second problem was minor: support class level
annotation for method without interceptor which was resolved by single
statement
binder.bindInterceptor(annotatedWith(Transactional.class),
not(annotatedWith(Transactional.class)), transactionInterceptor);
The solution is following:
...
final TransactionInterceptor transactionInterceptor = new
TransactionInterceptor(
transactionManager, new MyAnnotationTransactionAttributeSource()
);
binder.bindInterceptor(any(), annotatedWith(Transactional.class),
transactionInterceptor);
binder.bindInterceptor(annotatedWith(Transactional.class),
not(annotatedWith(Transactional.class)), transactionInterceptor);
...
public class MyAnnotationTransactionAttributeSource extends
AnnotationTransactionAttributeSource {
@Override
public TransactionAttribute getTransactionAttribute(Method method,
Class aClass) {
return super.getTransactionAttribute(method,
method.getDeclaringClass());
}
}
So my following service works as expected: read-only transactions for
all methods except save(User user)
@Transactional(readOnly = true)
public class UserServiceImpl implements UserService {
private final UserDAO _userDAO;
@Inject
public UserServiceImpl(UserDAO userDAO) {
_userDAO = userDAO;
}
public List<User> getUsers() {
return _userDAO.findAll();
}
public User getUser(Long id) {
return _userDAO.findById(id);
}
@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly =
false)
public void save(User user) {
_userDAO.saveOrUpdate(user);
}
}
P.S. I'm very happy about Guice :)
@Transactional(propagation = Propagation.REQUIRES_NEW , readOnly =
- Ivan
On Aug 14, 2:33 pm, "Dhanji R. Prasanna" <dha...@gmail.com> wrote:
> If you're using Hibernate or JPA consider Warp-persist which has similar
> transactional semantics:
>
> http://www.wideplay.com/guicewebextensions2
>
> > @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly =