views:

72

answers:

3
  1. We have base generic manager which is inherited by all managers. Base manager is annotated with @Transactional annotations.

  2. There are 2 groups of transactional services:

    • x.y.service1.* - have to be managed by transactionManager1
    • x.y.service2.* - have to be managed by transactionManager2

How can transactions be configured without nessesity to override ALL transactional methods and specify transaction manager?

@Transactional(readOnly = true)
public abstract class GenericManagerImpl<D extends IGenericDao, T extends BaseObject, PK extends Serializable>
        implements IGenericManager<T, PK> {

    protected D dao;

    @Autowired
    public void setDao(D dao) {
        this.dao = dao;
    }


    @Transactional(readOnly = false)
    public void save(T object) {
        dao.save(object);
    }

    @Transactional(readOnly = false)
    public void remove(T object) {
        dao.remove(object);
    }


}

@Service
class UserManagerImpl
        extends GenericManagerImpl<IUserDao, User, Long>
        implements IUserManager {

// Everything is OK. User is managed by txManager1

}

@Service
class BillingManagerImpl
        extends GenericManagerImpl<IBillingDao, Billing, Long>
        implements IBillingManager {

    @Override
    @Transactional(readOnly = false, value="txManager2") // <--have to override method only to specify txManager
    public void save(final Billing billing ) {
        super.save(billing);
    }

    @Override
    @Transactional(readOnly = false, value="txManager2") // <--have to override method only to specify txManager
    public void remove(final Billing billing ) {
        super.remove(billing);
    }
}
+1  A: 

I guess you can define @Transactional at class-level

@Service
@Transactional(readOnly = false, value="txManager2") 
class BillingManagerImpl ....
Bozho
I have read only adn NOT read only methods in base manager.I have 2 options here:1) have class level annotation @Transactional(readOnly = true) and method level annotation @Transactional(readOnly = false) for every NOT read only methods2) have class level annotation @Transactional(readOnly = false) and method level annotation @Transactional(readOnly = true) for every read only methodsIn any case i will need to override method level @transactional annotations for services which have to managed by txManager2
Seyran
+1  A: 

There is the possibility to create your own annotations as shortcuts for @Transactional(value="tx1"). (These can be used at class or method level)

from the reference documentation:

For example, defining the following annotations

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional("order")
public @interface OrderTx {
}

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional("account")
public @interface AccountTx {
}  

allows us to write the example from the previous section as

public class TransactionalService {

    @OrderTx
    public void setSomething(String name) { ... }

    @AccountTx
    public void doSomething() { ... }
  }
seanizer
+1, good idea..
Bozho
not mine, unfortunately. I only looked it up :-)
seanizer
Yes, i know that i can use meta annotation. But this is just simplifying of configuration. I will still need to override method and annotate it with annotation like @OrderTx
Seyran
A: 

Most probably i need to combine aop with @Transactional annotation.
Actually, what i want is:
1) To be able to configure transactions (read only flag, propogation, isolation etc) with @Transactional annotation.
2) define strategy to choose transaction manager outside of my classes (using AOP, for example)
x.y.service1.* -> use txManager1
x.y.service2.* -> use txManager2

Is it possible?

Seyran