【问题标题】:Spring database switching working for all users, but not per userSpring 数据库切换适用于所有用户,但不适用于每个用户
【发布时间】:2017-07-03 16:38:23
【问题描述】:

在我的 spring 项目中,我为不同的用户使用不同的数据库。为了支持这一点,我配置了 AbstractRoutingDataSource bean。

这是我的代码:

 @Primary
 @Bean(name="routingDatasource")
 public AbstractRoutingDataSource routingDatasource()
 {
     Map<Object, Object> targetDataSources=new HashMap<Object, Object>();

     targetDataSources.put(Db.comp1,dataSourceComp1());
     targetDataSources.put(Db.comp2,dataSourceComp2());

     AbstractRoutingDataSource dataSrc=new AbstractRoutingDataSource() {

        @Override
        protected Object determineCurrentLookupKey() {

            return DataBaseRouteFixer.getKey();
        }
    };

    dataSrc.setDefaultTargetDataSource(dataSourceComp2());
    dataSrc.setTargetDataSources(targetDataSources);
    System.out.println("abstract routing data source created");
    return dataSrc;
 }

Db 是一个枚举,在 Db 中我定义了一堆用户密钥。

数据库路由修复器:

@Component
public class DataBaseRouteFixer {

private static final ThreadLocal<Db> route=new ThreadLocal<Db>();

public static Db getKey() {
    return route.get();
}
public static void setKey(Db key) {
      route.set(key);
}

控制器中数据库的切换代码:

DataBaseRouteFixer.setKey(Db.comp1);

它工作正常,但是当我切换数据库时,相同的更改也会影响其他用户。我希望它为每个用户切换不同的数据库,我该怎么做?

【问题讨论】:

  • 在 Spring 默认情况下,单例中每个对象的作用域。因此,到达您服务器的每个请求都有相同的对象。如果您更改了该对象,现在每个请求都将使用该新对象。
  • 同意任何例子或建议?
  • 如果你想为每个请求使用不同的数据库,你可以制作范围原型的bean,但这太糟糕了。他们有什么选择可以将您的用户划分为某个类别吗??
  • 如果您可以将它们划分为某个类别,那么您可以为您拥有的每个数据库创建一个数据源对象。现在为每个数据库定义两个 dao 层对象一个。现在根据请求的用户类别,您可以使用相应的 dao 层对象。
  • 这里不能有两个dao层,即等于多个工程文件

标签: java spring spring-boot


【解决方案1】:

我建议创建代理数据源,它可以根据线程局部变量将所有调用委托给从 targetDataSources 映射中获取的正确真实数据源。

public class ProxyDataSource implements DataSource {
...
    @Override
    public Connection getConnection() throws SQLException {
        return getRealDataSource().getConnection();
    }
...
}

并在需要数据源的地方使用代理。

【讨论】:

    【解决方案2】:

    OP 需要为每个用户或一组用户使用不同的数据库。

    您可以将 Spring 会话 bean 用于有状态的 bean,它们的状态因用户而异。例如,这些可以是当前登录用户的偏好。

    spring 中 bean 的默认范围是单例的,在 Web 应用程序上下文中没有什么不同。

    【讨论】:

      【解决方案3】:

      就我而言,很难在多个用户之间实现抽象数据源路由。我需要使用hibernate来解决这个问题。我真正想要的是多租户。

      i found this article helpful

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-07
        • 2018-07-02
        • 1970-01-01
        • 1970-01-01
        • 2017-09-01
        • 2020-05-08
        相关资源
        最近更新 更多