当前位置: 首页 > 面试题库 >

动态数据源路由

尹超
2023-03-14
问题内容

对不起,我的英语不好。我为AbstractRoutingDataSource编写了实现:

public class DatabaseRoutingDataSource extends AbstractRoutingDataSource{

    @Override
    protected Object determineCurrentLookupKey() {      
        return DatabaseContextHolder.getDatabaseType();
    }

}

我创建了用于在数据库之间进行切换的新类:

public class DatabaseContextHolder {

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

    public static void setDatabaseType(DatabaseType databaseType) {
        contextHolder.set(databaseType);
    }

    public static DatabaseType getDatabaseType() {
        return (DatabaseType) contextHolder.get();
    }

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

其中DatabaseType为:

public enum DatabaseType {
    MAIN,
    BACKUP
}

在我的beans.xml中:

<bean id="mainDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="java:/jdbc/DBMIDS"/>
</bean>
<bean id="backupDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="java:/jdbc/DBMIDS2"/>
</bean>
<bean id="dataSource" class="DatabaseRoutingDataSource">
    <property name="targetDataSources">
        <map key-type="DatabaseType">
            <entry key="MAIN" value-ref="mainDataSource"/>
            <entry key="BACKUP" value-ref="backupDataSource"/>
        </map>
    </property>
    <property name="defaultTargetDataSource" ref="mainDataSource"/>
</bean>
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<bean id="databaseTarget" class="DatabaseBean">
    <property name="dataSource" ref="dataSource"/>
</bean>
<bean id="database" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager" ref="transactionManager"/>
    <property name="target" ref="databaseTarget"/>
    <property name="proxyInterfaces">
        <value>Database</value>
    </property>
    <property name="transactionAttributes">
        <props>
            <prop key="*">PROPAGATION_REQUIRED,-MyException</prop>
        </props>
    </property>
</bean>

现在,当我尝试更改DAO中的数据源时:

public class DatabaseBean extends JdbcDaoSupport implements Database
    public void myMethod() {
       DatabaseContextHolder.setDatabaseType(DatabaseType.MAIN);
       getJdbcTemplate().execute("INSERT INTO test(test) VALUES('test')");      
       DatabaseContextHolder.setDatabaseType(DatabaseType.BACKUP);
       getJdbcTemplate().execute("INSERT INTO test(test) VALUES('test')");        
}

首次执行getJdbcTemplate()时,一次调用一次defineCurrentLookupKey(),并且数据源不会切换。


问题答案:

Spring JDBC事务的事务管理的一部分是在事务开始时将连接绑定到线程。在事务结束且连接未绑定之前, 对同一数据源的
每个持久性操作都将使用相同的连接。因为您使用单个数据源来掩盖其他两个数据源,所以您只会获得一个连接。如果显式使用了两个单独的数据源,则每个都将被视为单独的资源,并且将启动单独的连接并将其绑定到每个线程。有关将JdbcDaoSupport和JdbcTemplate与事务一起使用的信息,请至少参阅参考指南中的“使资源与事务同步”。



 类似资料:
  • 问题内容: 我有一个Spring应用程序,我想动态更改数据源。当输入DS URL时,Spring Bean和所有依赖项将自动更新。我知道这有些奇怪,但是无论如何我都想实现。我的Spring配置如下: 问题是: JDBC URL存储在属性中,可以在运行时更改它。 更改URL后,我需要重新创建数据源,可能还需要重新创建相关对象。我不知道Spring如何优雅地做呢? 我知道Spring确实可以基于一个键

  • 我有一个Spring应用程序,我想动态更改数据源,即。当输入DS URL时,Spring bean和所有依赖项将自动更新。我知道这有点奇怪,但无论如何我想实现这一点。我的Spring配置如下: 问题是: > 一旦URL被更改,我需要重新创建数据源,可能还有依赖对象。我不知道如何在Spring优雅地做这件事? 我知道Spring可以基于一个键动态路由数据源,但数据源URL是在Spring中预定义的,

  • 如 动态 Inventory 所介绍,ansible可以从一个动态的数据源获取到inventory信息,包含云端数据源 怎么写一个自己的数据源? 很简单!我们仅仅需要创建一个在适当参数下,能够返回正确JSON格式数据的脚本或者程序,你可以使用任何语言来实现. 脚本规范 当我们在外部使用``–list``参数调用这个脚本时,这个脚本必须返回一个JSON散列/字典,它包含所管理的所有组.每个组的val

  • 我一直在尝试模块化我的React.js应用程序(它将作为带有Electron的桌面应用程序提供),如果我将来制作一个新模块,我只需添加一个新文件夹和修改几个文件,它就可以很好地集成。我最初受到这篇文章的启发:https://www.nylas.com/blog/react-plugins/ 在那之后,我开始尽可能多地研究,并最终创建了一个JSON文件,该文件将保存在服务器中,其中包含为特定客户机注

  • 我有一个关于如何在Spring Boot应用程序中处理两个不同数据源的问题。 用例: 我有一个必须始终连接的主存储库(db)(应用程序范围),我对此没有问题,有TransactionManager和EntityManager。 第二个数据库连接应该只有请求范围,并从httpRequest收集动态凭据。 数据源都来自PostgreSQL。 这可能吗?如果可能,实现这一目标的最佳方法是什么? 谢谢你的

  • Bluemix上的Node-RED,使用语言翻译器节点,留档如下; 源和目标语言参数可以通过编辑器面板进行配置,也可以使用以下属性msg中的语言代码进行动态设置。加味精。德斯特朗。 设置msg.srclang 是否可以使用Bluemix上的语言转换器节点动态设置源/目标语言值? 谢谢, 罗南