我需要创建一个多属性应用程序,能够在我的java代码中切换模式(不是基于用户请求)。
我读过文章: https://fizzylogic.nl/2016/01/24/make-your-spring-boot-application-multi-tenant-aware-in-2-steps/ http://www.greggbolinger.com/tenant-per-schema-with-spring-boot/ 当在Rest-request中传递模式时,解决方案可以正常工作。
但是我需要实现以下逻辑:
public void compare(String originalSchema, String secondSchema){
TenantContext.setCurrentTenant(originalSchema);
List<MyObject> originalData = myRepository.findData();
TenantContext.setCurrentTenant(secondSchema);
List<MyObject> migratedData = myRepository.findData();
}
关键是,当我手动设置TenenantContext时,没有切换连接。 MultiTenantConnectionProviderImpl.getConnection仅在第一次调用我的存储库时调用。
@Component
public class MultiTenantConnectionProviderImpl implements MultiTenantConnectionProvider {
@Override
public Connection getConnection(String tenantIdentifier) throws SQLException {
final Connection connection = getAnyConnection();
try {
connection.createStatement().execute( "ALTER SESSION SET CURRENT_SCHEMA = " + tenantIdentifier );
}
catch ( SQLException e ) {
throw new HibernateException(
"Could not alter JDBC connection to specified schema [" + tenantIdentifier + "]",e);
}
return connection;
}
}
是否可以强制切换会话?
答案 0 :(得分:1)
嗯,你需要它
public interface Service {
List<MyObject> myObjects();
}
@Service
@Transactional(propagation = Propagation.REQUIRES_NEW)
public class ServiceImpl implements Service {
@Autowired
private MyRepository myRepository;
@Override
public List<MyObject> myObjects() {
return myRepository.findData();
}
}
@Service
public class AnotherService() {
@Autowired
private Service service;
public void compare(String originalSchema, String secondSchema){
TenantContext.setCurrentTenant(originalSchema);
List<MyObject> originalData = service.myObjects();
TenantContext.setCurrentTenant(secondSchema);
List<MyObject> migratedData = service.myObjects();
}
}
答案 1 :(得分:1)
找到一个硬编码的解决方案。
@Service
public class DatabaseSessionManager {
@PersistenceUnit
private EntityManagerFactory entityManagerFactory;
public void bindSession() {
if (!TransactionSynchronizationManager.hasResource(entityManagerFactory)) {
EntityManager entityManager = entityManagerFactory.createEntityManager();
TransactionSynchronizationManager.bindResource(entityManagerFactory, new EntityManagerHolder(entityManager));
}
}
public void unbindSession() {
EntityManagerHolder emHolder = (EntityManagerHolder) TransactionSynchronizationManager
.unbindResource(entityManagerFactory);
EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager());
}
}
每个块,在新的tenantContext中加载数据应执行以下操作:
databaseSessionManager.unbindSession();
TenantContext.setCurrentTenant(schema);
databaseSessionManager.bindSession();
//execute selects