行级策略中的应用程序用户:如何设置会话变量

Application users in row-level policies: how to set session variables

我正在尝试编写在执行查询之前检查用户权限的行级策略。在这种情况下,我需要能够在从连接池中获取连接时设置一个包含用户标识符的会话变量,并在连接返回池时 unset/release 设置相同的会话变量。以下博客可能会提供一个很好的背景来解释我正在尝试做的事情:https://blog.2ndquadrant.com/application-users-vs-row-level-security/

在我的设置中,我有以下图层:

  1. 光:HikariDataSource
  2. Spring:TransactionAwareDataSourceProxy(使用Hikari数据源),DataSourceTransactionManager(使用Hikary数据源)
  3. jOOQ:DataSourceConnectionProvider(使用 Spring 数据源),DefaultDSLContext

前两层仅供内部使用。也就是说,应用程序中的所有查询都是通过最后一层 jOOQ 完成的。

所以,我需要能够在连接 take from poolgive back to pool 上实现回调。

我一直在查看 Hikari 和 Spring 的文档,但找不到任何有用的信息。这可能是我的第一个问题:Hikari and/or Spring 是否提供此类回调?

我调查的下一步是 jOOQ。我偶然发现了 ExecuteListener。这是我的后续问题:ExecuteListener 是一个很好的应用程序吗?这并没有实现连接被获取和返回时的实际点,但是 execution context 对我来说可能已经足够好了(因为我所有的查询都是在 jOOQ 中完成的)?如果是这样,我应该实现 startend 函数吗?

这可以在您当前堆栈的不同级别上解决。这里有两个建议:

DataSource / Connection 代理中解决此问题

大多数连接池实现以下语义:

因此,您可以代理这两个 API 并在这些相关方法中实现您想要的语义。这需要更多工作,但它适用于任何 JDBC 客户端,包括 jOOQ(即,当您不使用 jOOQ 时它也可以工作)

在 jOOQ 中解决这个问题

如果您所有的数据库交互都通过 jOOQ,您可以直接使用 jOOQ 更轻松地解决这个问题,使用 ConnectionProvider SPI,它包含两个完全符合您要求的语义的方法:

因此,除了使用 jOOQ 的开箱即用 DataSourceConnectionProvider,您还可以这样做:

public class MyConnectionProvider implements ConnectionProvider {

    // Configure spring to inject your data source here
    @Autowire
    DataSource ds;

    @Override
    public Connection acquire() {
        try {
            Connection c = ds.getConnection();
            // Do your stuff here
            return c;
        }
        catch (SQLException e) {
            throw new DataAccessException("Something failed", e);
        }
    }

    @Override
    public void release(Connection c) {
        try {
            // Do your stuff here
            c.close();
        }
        catch (SQLException e) {
            throw new DataAccessException("Something failed", e);
        }
    }
}

您也可以使用 ExecuteListener 来执行此操作,但上述方法肯定更简单。