我想用两个不同的数据库节点配置@transactional注释。
如果一个数据库节点发生故障,那么事务管理器应与第二个节点一起正常工作。
如果数据库节点在事务之间失败,那么它也应与第二个节点一起使用。是否有任何方法可以在春季进行配置
答案 0 :(得分:0)
您可以根据情况采用多租户方式
请参见https://dzone.com/articles/spring-boot-hibernate-multitenancy-implementation
您需要重写MultiTenantConnectionProviderImpl方法
public Connection getConnection(String tenantIdentifier)
public Connection getAnyConnection()
如果第一个失败则检查并返回第二个DataSource连接。
但这不是一个简单的任务。
答案 1 :(得分:0)
尽管上面已经提供了答案,但我将再次发布更多详细信息,
我同意您可以将MultiTenantConnectionProviderImpl
与CurrentTenantIdentifierResolver
一起使用,我已经实现了很长一段时间,并且正在发布代码以寻求更多帮助。
首先要了解两者的目的。
CurrentTenantIdentifierResolver
用于标识要用于给定租户的连接,为此,您需要一个租户标识。对于租户识别的逻辑,您可以覆盖它。就您而言,它是固定的,即,您将始终指向第一个数据库。
public class TenantIdentifierAndSchemaResolver implements CurrentTenantIdentifierResolver {
private String tenantIdentifier = "FIRST_DATABASE";
@Override
public String resolveCurrentTenantIdentifier() {
return this.tenantIdentifier;
}
/**
* Reason why it retuns a false is because we don't want to validate the
* tenant identifier in the current session.
*
* Please read below.
* {@link CurrentTenantIdentifierResolver#validateExistingCurrentSessions()}
*/
@Override
public boolean validateExistingCurrentSessions() {
return false;
}
public void setTenantIdentifier(String tenantIdentifier) {
this.tenantIdentifier = tenantIdentifier;
}
}
此后,您需要实现MultiTenantConnectionProvider
,您将实际使用该public class CustomMultiTenantConnectionProvider implements MultiTenantConnectionProvider {
private static final long serialVersionUID = 9033113494774715973L;
private Logger LOG = LogManager.getLogger(CustomMultiTenantConnectionProvider.class);
private BasicDataSource dataSource;
public void setDataSource(BasicDataSource dataSource) {
this.dataSource = dataSource;
}
@Override
public Connection getAnyConnection() throws SQLException {
if (LOG.isDebugEnabled()) {
LOG.debug("Fetching any connection >");
}
return dataSource.getConnection();
}
@Override
public Connection getConnection(String tenantIdentifier) throws SQLException {
Connection tenantSpecificConnection = dataSource.getConnection();
if (!StringUtils.isEmpty(tenantIdentifier)) {
Statement statement = tenantSpecificConnection.createStatement();
statement.executeQuery("use " + tenantIdentifier);
statement.close();
tenantSpecificConnection.setSchema(tenantIdentifier);
} else {
tenantSpecificConnection.setSchema(Constants.SOMEOTHER_DB);
}
return tenantSpecificConnection;
}
@Override
public void releaseAnyConnection(Connection connection) throws SQLException {
if (LOG.isDebugEnabled()) {
LOG.debug("Releasing connection obtained by : getAnyConnection", connection);
}
connection.close();
}
@Override
public void releaseConnection(String tenantIdentifier, Connection connection) throws SQLException {
if (LOG.isDebugEnabled()) {
LOG.debug("Releasing connection for : {}", tenantIdentifier);
}
connection.close();
}
/**
* does the connection provider has support for releasing connection and get
* back the connection as and when needed ?
*
* @return
*/
@Override
public boolean supportsAggressiveRelease() {
return false;
}
@SuppressWarnings("rawtypes")
@Override
public boolean isUnwrappableAs(Class arg0) {
return false;
}
@Override
public <T> T unwrap(Class<T> arg0) {
return null;
}
}
切换传入请求的数据库。
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="org.opensource.example" />
<property name="hibernateProperties">
<map>
<entry key="hibernate.hbm2ddl.auto" value="update"></entry>
<entry key="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"></entry>
<entry key="hibernate.connection.charSet" value="UTF-8"></entry>
<entry key="hibernate.multiTenancy" value="SCHEMA"></entry>
<entry key="hibernate.tenant_identifier_resolver" value-ref="multitenantSchemaResolverAndTenantIdentifier"></entry>
<entry key="hibernate.multi_tenant_connection_provider"
value-ref="multitenantConnectionProvider"></entry>
<entry key="hibernate.show_sql" value="true"></entry>
<entry key="hibernate.use_sql_comments" value="true"></entry>
<entry key="hibernate.connection.charSet" value="UTF-8"></entry>
</map>
</property>
</bean>
您需要在spring配置中声明这些bean,并在hibernate配置中指定它。
var a = " a @b c "
console.log(a.split(" "))
["", "a", "b", "c", ""]
我希望这会有所帮助。