动态数据源路由 - 数据源路由器未初始化

2024-01-31

我指的是这个article https://spring.io/blog/2007/01/23/dynamic-datasource-routing/,其中我们可以使用 Spring Framework 中的 AbstractRoutingDataSource 来动态更改应用程序使用的数据源。我正在使用 Mybatis (3.3.0) 和 Spring (4.1.6.RELEASE)。如果从主数据库获取数据时发生异常,我想切换到备份数据库。在这个例子中,我使用了 hsql 和 mysql db。

路由数据源:

public class RoutingDataSource extends AbstractRoutingDataSource {

@Override
protected Object determineCurrentLookupKey() {
    return DataSourceContextHolder.getTargetDataSource();
 }
}

数据源上下文持有者:

public class DataSourceContextHolder {

private static final ThreadLocal<DataSourceEnum> contextHolder = new ThreadLocal<DataSourceEnum>();

public static void setTargetDataSource(DataSourceEnum targetDataSource) {
    contextHolder.set(targetDataSource);
}

public static DataSourceEnum getTargetDataSource() {
    return (DataSourceEnum) contextHolder.get();
}

public static void resetDefaultDataSource() {
    contextHolder.remove();
 }
}

应用程序数据配置:

@Configuration
@MapperScan(basePackages = "com.sample.mapper")
@ComponentScan("com.sample.config")
@PropertySource(value = {"classpath:app.properties"},
                ignoreResourceNotFound = true)
public class ApplicationDataConfig {

@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
    PropertySourcesPlaceholderConfigurer configurer =
        new PropertySourcesPlaceholderConfigurer();
    return configurer;
}

@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean() throws Exception {
    SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
    RoutingDataSource routingDataSource = new RoutingDataSource();
    routingDataSource.setDefaultTargetDataSource(dataSource1());
    Map<Object, Object> targetDataSource = new HashMap<Object, Object>();
    targetDataSource.put(DataSourceEnum.HSQL, dataSource1());
    targetDataSource.put(DataSourceEnum.BACKUP, dataSource2());
    routingDataSource.setTargetDataSources(targetDataSource);
    sessionFactory.setDataSource(routingDataSource);
    sessionFactory.setTypeAliasesPackage("com.sample.common.domain");

    sessionFactory.setMapperLocations(
        new PathMatchingResourcePatternResolver()
            .getResources("classpath*:com/sample/mapper/**/*.xml"));

    return sessionFactory;
}

@Bean
public DataSource dataSource1() {
    return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.HSQL).addScript(
            "classpath:database/app-hsqldb-schema.sql").addScript(
            "classpath:database/app-hsqldb-datascript.sql").build();
}


@Bean
public DataSource dataSource2() {
    PooledDataSourceFactory pooledDataSourceFactory = new PooledDataSourceFactory();
    pooledDataSourceFactory.setProperties(jdbcProperties());
    return pooledDataSourceFactory.getDataSource();
}

@Bean
protected Properties jdbcProperties() {
    //Get the data from properties file
    Properties jdbcProperties = new Properties();
    jdbcProperties.setProperty("url", datasourceUrl);
    jdbcProperties.setProperty("driver", datasourceDriver);
    jdbcProperties.setProperty("username", datasourceUsername);
    jdbcProperties.setProperty("password", datasourcePassword);
    jdbcProperties.setProperty("poolMaximumIdleConnections", maxConnectionPoolSize);
    jdbcProperties.setProperty("poolMaximumActiveConnections", minConnectionPoolSize);

    return jdbcProperties;
}
}

Client:

 @Autowired
 private ApplicationMapper appMapper;

public MyObject getObjectById(String Id) {
    MyObject myObj = null;
    try{
        DataSourceContextHolder.setTargetDataSource(DataSourceEnum.HSQL);
        myObj = appMapper.getObjectById(Id);
    }catch(Throwable e){
        DataSourceContextHolder.setTargetDataSource(DataSourceEnum.BACKUP);
        myObj = appMapper.getObjectById(Id);  
    }finally{
        DataSourceContextHolder.resetDefaultDataSource();
    }
    return getObjectDetails(myObj);
}

我收到以下异常

### Error querying database.  Cause: java.lang.IllegalArgumentException: DataSource router not initialized

但是,如果我一次只使用一个数据库,我就可以让事情正常工作,这意味着数据源配置没有问题。


您可以尝试一次最后一行吗(以相同的顺序):-

targetDataSource.put(DataSourceEnum.HSQL, dataSource1());
targetDataSource.put(DataSourceEnum.BACKUP, dataSource2());
routingDataSource.setTargetDataSources(targetDataSource);

routingDataSource.afterPropertiesSet();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

动态数据源路由 - 数据源路由器未初始化 的相关文章

随机推荐

  • 使用 getevent 在已 root 的 Android 手机上拒绝权限

    我有非常简单的代码如下 Override public void onClick View v Log i MyApp Started try Process processStart Runtime getRuntime exec su
  • 如何使用右/左在sqldf中分割变量,如left(x,n)

    R 中是否有不同的函数可以用来获得与 SQL 中左函数或右函数相同的结果 例如 以下 SQL 查询将给出列的前 6 个字符 select left x 6 from table 但是 当我在 sqldf 中尝试这样做时 如下所示 sqldf
  • 如何计算图像的直方图?

    我该如何解决以下错误 import cv2 img cv2 imread home monojit Desktop crop jpg hsv cv2 cvtColor img cv2 COLOR BGR2HSV hist cv2 calcH
  • R 是否有依赖于系统的功能?

    我的同事希望确保我们在 R 中的工作独立于平台 特别是代码可以在 Linux Mac 和 Windows 上运行 并且在一个系统上创建的文件可以在其他系统上运行 由于这个问题之前在我的团队中出现过 我希望得到一个笼统的答案 这将使我更容易自
  • 一段时间后,条形码扫描仪抛出 java.lang.UnsatisfiedLinkError

    我有一个使用新的 Android 视觉库的条形码扫描仪 它在我的设备和其他几个设备上完美运行 但突然它停止工作 我在日志中看到以下异常 No implementation found for com google android gms v
  • Unity中如何设置文本的字体大小?

    如何使标签中的字体变大 我用这个函数来显示文本 function OnGUI GUI color Color green GUI Label Rect 500 350 200 50 Lose 结果是 我怎样才能把这个文字变大 只需创建一个合
  • 如何从我的程序中列出 Internet Explorer 使用的插件 (BHO)?

    我需要在我的 Win32 独立程序中检索 当前安装的 Internet Explorer 加载项列表 浏览器帮助程序对象 以及 如果可能 它们的启用 禁用状态 由于反间谍软件程序 或例如Autoruns https technet micr
  • go lang中按不同维度对点(结构)进行排序

    我有一个 Points 类型的多维点列表 我已经实施了sort Sort界面 现在可以排序y value e g type Points Point func points Points Len int return len points
  • 当视图不与模型交互时,这就是 MVC 吗?

    我设计了一个 MVC 在 NET 中 其中视图没有到模型的链接 它只知道控制器 传统的 MVC 模式的所有部分都相互通信 就我而言 控制器基本上是一个调解者 这会将任何异常或逻辑排除在视图之外 它对模型的依赖性为零 这不再是 MVC 了吗
  • 使用 Three.js 单击网格获取像素的颜色值

    我正在使用 Three js 的最新版本 我得到了一个带有 2D 网格和渐变颜色的场景 颜色取决于分配给每个顶点的值 我想通过用鼠标单击渐变的每个点来获取它的值 通过获取颜色 并对我的值进行一些数学计算 我尝试使用这样的系统 因为它在这里工
  • 使用toggleClass更改类后的jQuery事件

    我对 jQuery 和toggleClass 有疑问 我想创建一个 div 单击按钮即可关闭 按钮发生变化 当我再次单击此按钮时 div 将再次打开 问题是 当我单击按钮时 div 关闭并且按钮的类发生变化 这很好 但现在 当我单击新类的按
  • fread EOF 而不是分隔符

    我正在尝试用 fread 读取一个大文件 但我猜文件的布局有些混乱 如果我尝试读取文件 data fread input data txt sep t 在此文件上 我只是选择了有错误的行以及前后的一些内容 ID imdbID Title Y
  • 用 Python 封装旧版 Fortran。使用 setuptools 和 numpy.distutils 可以吗?

    我正在尝试为我的领域中一些流行的 Fortran 代码制作一个 python 包发行版 我希望它使用最标准的方法setup py文件 相关问题对学习有帮助如何包装 Fortran 扩展 https stackoverflow com que
  • 如何在新版Android Studio中添加classpath

    我将 android studio 版本更新为 bumblebee 版本 现在我想将导航组件添加到我的项目中 我想将类路径添加到 gradle 但是这个文件 gradle 已更改 我不知道如何添加它 我想添加这个 classpath and
  • 如何使用 Node.js 中的本机 Promise 全局处理异常?

    我知道怎么做处理承诺中的特定错误 https stackoverflow com questions 21800010 how do i handle errors with promises但有时我的代码片段看起来像这样 someProm
  • jquery ui - 模式对话框(创建模式内容的更好方法?)

    有没有办法在 JavaScript 中定义模式内容 而不是总是必须在页面上有一个元素并从中创建对话框 它有标题选项 因此我可以 动态 创建模态标题 但实际内容呢 就像说我需要它说 你要删除图像 539 而不是为每个可能的图像创建一个模式 或
  • NoSQL - MongoDB 与 CouchDB [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 对于 NoSQL 运动 我完全是个菜鸟 我听说过很多关于 MongoDB 和 CouchDB 的事情 我知道两者之间存在差异 作为进入 NoSQ
  • 在 cakephp 2.0 中运行插件的 shell

    我创建了一个新的 CakePHP 2 0 应用程序 并且想要运行插件的 shell
  • 抛出异常还是阻止异常?

    问题是是否更愿意Throw an exception或防止其发生 这是一个游戏项目 IndexOutOfBoundsException与围绕它进行编码相比 我有一个List
  • 动态数据源路由 - 数据源路由器未初始化

    我指的是这个article https spring io blog 2007 01 23 dynamic datasource routing 其中我们可以使用 Spring Framework 中的 AbstractRoutingDat