2010-07-19 11 views
8

Merci d'avoir lu ceci.Spring: source de données séparée pour les transactions en lecture seule

J'ai 2 bases de données MySQL - maître pour les écritures, esclave pour les lectures. Le scénario parfait que j'imagine est que mon application utilise la connexion au maître pour les transactions readOnly=false, l'esclave pour les transactions readOnly=true.

Afin de mettre en œuvre cela, je dois fournir une connexion valide en fonction du type de transaction en cours. Ma couche de service de données ne doit pas savoir quel type de connexion elle utilise et il suffit d'utiliser le SqlMapClient injecté (j'utilise iBatis) directement. Cela signifie que (si je comprends bien), les SqlMapClient injectés devraient être mandatés et le délégué devrait être choisi lors de l'exécution.

public class MyDataService { 

    private SqlMapClient sqlMap; 

    @Autowired 
    public MyDataService (SqlMapClient sqlMap) { 
     this.sqlMap = sqlMap; 
    } 

    @Transactional(readOnly = true) 
    public MyData getSomeData() { 
     // an instance of sqlMap connected to slave should be used 
    } 

    @Transactional(readOnly = false) 
    public void saveMyData(MyData myData) { 
     // an instance of sqlMap connected to master should be used 
    } 
} 

Donc la question est - comment puis-je faire?

Merci beaucoup

Répondre

4

Il est une idée intéressante, mais vous auriez un travail difficile sur vos mains. L'attribut readOnly est conçu comme un indice pour le gestionnaire de transactions, et n'est vraiment consulté nulle part. Vous devez réécrire ou étendre plusieurs classes d'infrastructure Spring.

Donc, à moins que vous n'ayez vraiment envie de faire fonctionner ce que vous voulez, votre meilleure option est certainement d'injecter deux objets distincts SqlMapClient dans votre DAO, et pour que les méthodes choisissent la bonne. Les annotations @Transactional doivent également indiquer quel gestionnaire de transactions utiliser (en supposant que vous utilisez DataSourceTransactionManager plutôt que JpaTransactionManager), en prenant soin de faire correspondre le gestionnaire de transactions au DataSource utilisé par le SqlMapClient.

+0

Existe-t-il un moyen plus simple avec AspectJ par exemple? – artemb

+0

@artemb: Je suis sûr que AspectJ serait utile, mais ça ne va pas être facile. – skaffman