多数据源

Jul 10, 2017 10:38:44 AM

概述

由于这个问题经常被问到,nutzcn社区累计了好几十个帖子,所以有必要单独开个文档描述一下

在一些复杂或遗留系统中,通常需要操作两个或更多的数据源.

总的原则: NutDao与DataSource是一对一关系.

值得注意的是, javax.sql.DataSource只是一个接口,而且NutDao只会调用其getConnection()方法.

配对模式在Ioc中的示例

你可以定义无数个dataSourceXXX,只要它们使用不一样的名称, 然后建立对应的N个NutDao实例

每个NutDao实例,均refer对应的dataSource

  1. // 主数据库
  2. dataSource : {
  3. // 按标准的写法
  4. },
  5. // 主Dao实例
  6. dao : {
  7. type : "org.nutz.dao.impl.NutDao",
  8. args : [{refer:"dataSource"}] //引用主数据源
  9. },
  10. //--------------------------------------------------------
  11. // 第三方订单数据库
  12. dataSourceOrder : {
  13. // 同样是标准的写法
  14. },
  15. daoOrder : {
  16. type : "org.nutz.dao.impl.NutDao",
  17. args : [{refer:"dataSourceOrder"}] //引用第三方数据源
  18. },
  19. //--------------------------------------------------------
  20. // 遗留数据库
  21. dataSourceOld : {
  22. // 同样是标准的写法
  23. },
  24. daoOld : {
  25. type : "org.nutz.dao.impl.NutDao",
  26. args : [{refer:"dataSourceOld"}] //引用第三方数据源
  27. },

在Module/Service类中的注入

  1. // 非父类字段的注入
  2. @Inject
  3. protect Dao dao; // 注入主Dao实例
  4. @Inject
  5. protect Dao daoOrder; // 注入第三方订单数据库Dao实例
  6. // 通过父类字段的注入,通常是继承的EntityService的服务类.
  7. @IocBean(args={"refer:daoOrder"})
  8. // 效果是: 调用dao()返回的将是daoOrder实例.

多数据源下的事务模板

在一般情况下,Trans.exec下,多个数据源下的事务能正常工作,除特殊的情况: 某个数据源commit时报错,之前已经commit的数据源无法回滚.

假设有A,B,C三个数据源

  1. Trans.exec(new Atom(){
  2. public void run() {
  3. dao.insert(user);
  4. daoOrder.insert(order);
  5. daoOld.insert(report);
  6. }
  7. });

事务执行时序

  1. begin > dao
  2. begin > daoOrder
  3. begin > daoOld
  4. commit > dao
  5. commit > daoOrder
  6. commit > daoOld #出错
  7. rollback > dao # 回滚失败,因为已经commit过
  8. rollback > daoOrder # 回滚失败,因为已经commit过
  9. rollback > daoOld # 可能也失败,但没有提交成功

以上特殊情况,是任何基于标准JDBC驱动的ORM都无法回避的. 走XA的JDBC API才可能解决.

本页面的文字允许在知识共享 署名-相同方式共享 3.0协议GNU自由文档许可证下修改和再使用。

原文: http://nutzam.com/core/dao/multiple_datasource.html