gpt4 book ai didi

java - 动态数据源路由

转载 作者:行者123 更新时间:2023-11-29 07:18:31 27 4
gpt4 key购买 nike

抱歉我的英语不好。我为 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();
}
}

数据库类型是:

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')");
}

determineCurrentLookupKey()调用一次,当第一次执行getJdbcTemplate()时,数据源不切换。

最佳答案

JDBC 事务的 Spring 事务管理的一部分是在事务开始时将连接绑定(bind)到线程。在事务结束并且连接未绑定(bind)之前,同一数据源上的每个持久性操作 都将使用同一连接。因为您使用单个数据源来屏蔽其他两个数据源,所以您只会获得一个连接。如果您显式使用两个单独的数据源,每个数据源都将被视为一个单独的资源,并且将启动一个单独的连接并绑定(bind)到每个数据源的线程。参见 "Synchronizing resources with transactions"在引用指南中,至少可以了解当您将事务与 JdbcDaoSupport 和 JdbcTemplate 一起使用时,幕后发生的事情的提示。

关于java - 动态数据源路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7304019/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com