AbstractRoutingDataSource对象是spring中对多数据源实现路由功能的一个类,从名字上很容易想到在多数据源中的应用,但这里依然有个坑需要注意,就是对多数据源的使用场景。不是任何场景都适合。笔者也是在使用中遇到了问题,在网上查了很多资料。发现和我有同样问题的人不少。特将对它的理解写在此处,以备日后使用。如有不对地方还请高人指正。
一般我们在实际中对多数据源的使用都是在Service层调用Dao层,而最佳实践经验是分包管理数据源,在Service层调用多个不同数据源的Dao对象,来完成一个业务,这通常都需要事务来处理数据一致性问题。而使用AbstractRoutingDataSource来管理数据源的问题就出现在了事务上,我们知道事务也是需要配置数据源的。如果我们要用AbstractRoutingDataSource来实现数据源的切换,在事务面前是无能为力的。这主要是因为一般我们的事务是以AOP的方式切在我们业务方法之前的,并且是通过获取Connection对象来实现的(这应该是事务的通用方式),而事务本身也包含数据源,恰好和从AbstractRoutingDataSource对象中切换数据源的时机重合,就是调用determineTargetDataSource方法,这也是我们实现AbstractRoutingDataSource类唯一要覆盖的方法。所以在连接池的环境下,就导致由事务创建了链接也就是调用了determineTargetDataSource方法。如果我们要向切换数据源就必须要在事务之前完成,但这就无法实现在事务中使用多数据源了。
总结,AbstractRoutingDataSource只适用于多数据源中一业务一数据源的情况。如果是一业务多个数据源,还是老老实实的分包,分SessionFactory吧。这样可以用Atomikos+jta来实现数据的一致性。