当前位置: 首页 > 知识库问答 >
问题:

手动更改多租户会话

甄成弘
2023-03-14

我需要创建一个多租户应用程序,能够在我的java代码中切换模式(不是基于用户请求)。

我读过文章:当架构在 Rest-request 中传递时,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/ 解决方案工作正常。

但是,我需要实现以下逻辑:

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;
    }
 }

是否可以强制切换会话?

共有3个答案

闾丘坚诚
2023-03-14

尝试使用

spring.jpa.open-in-view=false

在您的应用程序属性文件中。

更多信息 这个
spring.jpa.open-in-view=Spring Boot 中的真属性是什么?

希望这有所帮助..

阳狐若
2023-03-14

好吧,你需要它

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();
    }
}
魏鹤轩
2023-03-14

找到了一个硬编码的解决方案

@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
 类似资料:
  • 目前为止,我们已经让用户页面在多租户风格下工作。为使它工作,我们看起来并没有做太多的变化。但请记住,我们正在对一个原来不是多租户的系统作修改。 让我们在 Roles 表应用类似的原则。 再一次,一个租户的用户在不能查看或修改其他租户的角色,每个租户的用户是相互独立工作的。 我们先在 RoleRow.cs 添加 TenantId 属性: namespace MultiTenancy.Administ

  • 问题内容: Tl; dr:有没有方法可以覆盖默认行为? 在我的django项目中,我有很多网址,例如 允许使用以下网址 这样,我便可以使用自定义中间件来修改请求,以包括基于使用我的网站的公司的一些特定详细信息 这一切工作正常,除了当Django试图破译与完整路径和… 它似乎作为正则表达式的默认匹配返回。由于该方法具有用于映射到的转义映射 该标签我已经能够覆盖更换正确的公司名称,我想知道是否有类似的

  • 我使用和配置了hibernate的多租户。我还编写了一个过滤器,截取url并确定谁是租户。 我有几个问题/困惑。 > 这种方法合适吗?我也想过在用户会话中存储租户标识,但我认为这不是一个好主意。(在过去,我在会话中存储东西时遇到过问题,在某些情况下有其局限性)。 我对这两种方法感到困惑,请问还有第三种方法吗。对于多租户,我选择了hibernate的策略。

  • 由于我们现在有一个行为处理仓储的详细信息,我们只需在行(rows)实现 IMultiTenantRow 接口并添加 TenantId 属性。 从 SupplierRow.cs 开始: namespace MultiTenancy.Northwind.Entities { //... public sealed class SupplierRow : Row, IId

  • 我们正面临着解决这个问题的艰难时刻!我们正在尝试在不使用默认租户的情况下为Spring Boot服务使用MTA。这意味着当当前上下文中没有租户时,我们希望从我们的CurrentTenantIdentifierResolver实现返回null。这在我们用JavaEE+Hibernate+Deltaspike数据构建的其他服务中运行良好,但在Spring服务启动时失败。 异常消息如下:“由:org.h

  • 我们在 Users 表中添加一个 TenantId 字段,但是没有在 UserRow 中定义,并且也不能在用户对话框中看到该字段。 该字段只能被 admin 用户查看和编辑。即使是授予了访问管理租户权限的其他用户也不能查看或者修改这些信息。 首先把 TenantId 字段添加到 UserRow.cs: namespace MultiTenancy.Administration.Entities {