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

JPA:如何设置MySQL会话变量?

杜河
2023-03-14

我需要为我的应用程序设置一个mysql会话变量,以便按照预期使用MariaDB Galera集群。SQL调用是:set SESSION wsrep_sync_wait=1。当应用程序使用数据库时,应始终设置该值。我使用EclipseLink作为JPA提供程序。

我的问题是:实现这一点的最佳途径是什么?

public class SessionCustomizerImpl implements org.eclipse.persistence.config.SessionCustomizer {

    private final static String WSREP_SYNC_WAIT_CHECK_SQL = "SHOW SESSION VARIABLES LIKE 'wsrep_sync_wait'";
    private final static String WSREP_SYNC_WAIT_SET_SQL = "SET SESSION wsrep_sync_wait = 1";

    @Override
    public void customize(Session session) throws Exception {
        Vector result = session.executeSQL(WSREP_SYNC_WAIT_CHECK_SQL);
        if ((result != null) && !result.isEmpty()) {
            session.executeNonSelectingSQL(WSREP_SYNC_WAIT_SET_SQL);
            // Galera connection detected; wsrep_sync_wait set to 1
        } else {
            // No Galera connection detected; wsrep_sync_wait not set
        }

    }
}

这对我不起作用。从EntityManager查询会话变量将返回0值。

选项2:EntityManager工厂

每次创建新的EntityManager时,都会执行SQL。

public class SyncWaitEntityManagerFactory implements Factory<EntityManager> {
    private final EntityManagerFactory emf;

    @Inject
    public SyncWaitEntityManagerFactory(EntityManagerFactory emf) {
        this.emf = emf;
    }

    @Override
    public EntityManager provide() {
        final EntityManager em = emf.createEntityManager();
        // set it
        em.getTransaction().begin();
        em.createNativeQuery("SET SESSION wsrep_sync_wait = 1").executeUpdate();
        em.getTransaction().commit();

        return em;
    }

    @Override
    public void dispose(EntityManager instance) {
        if (instance.isOpen()) {
            instance.close();
        }
    }

}
    String jdbcUrl = "jdbc:mysql://db.example.test:3306/"+ JDBC_DB 
            +"?sessionVariables=wsrep_sync_wait=1";
    Properties p = new Properties();
    p.put("javax.persistence.jdbc.url", jdbcUrl);
    p.put("javax.persistence.jdbc.user", JDBC_USER);
    p.put("javax.persistence.jdbc.password", JDBC_PASSWORD);
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("myPU", p);

    EntityManager entityManager = emf.createEntityManager();

不错的解决方案。为我工作;无需努力,无需交易。缺点:我不能捕捉异常(例如:首先检查变量是否存在,然后设置它--允许在不支持/使用这个特定变量的系统上部署代码)。

共有1个答案

萧晔
2023-03-14

您还可以在每次调用getConnection()时使用一个方面来执行查询,这基本上是针对每个事务(在调用之后设置方面,以便我们有一个有效的连接对象):

@Component
@Aspect
public class CustomConnectionPreparer implements ConnectionPreparer
{
    @AfterReturning(pointcut = "execution(* *.getConnection(..))", returning = "connection")
    public Connection prepare(Connection connection) throws SQLException {
        // execute the query (also exception handling)
        try (Statement statement = connection.createStatement()) {
            statement.execute("SELECT 1");
        } catch (SQLException e) {
            throw e;
        }
    
        return connection;
    }
}
 类似资料:
  • 我想设置会话点击链接,所以登录后,用户将重定向到上次访问的页面。 例如: 步骤1:用户打开主页。(seesion url设置为主页 第二步:下一步在新选项卡中,用户将打开联系人页面(再次会话变量重置) 第三步:用户进入首页,点击登录链接。(因为没有重新加载页面,所以没有设置会话) 第四步:登录后,用户将重定向到联系人页面。 但这里我想要用户被重定向到用户点击链接登录的地方。 我试着用下面的代码,但

  • 问题内容: 我有以下问题…我想在单击普通链接时设置会话变量,例如: 我的研究似乎指出,PHP无法以设置会话变量的方式赶上click事件。 我相信使用Ajax是可能的,但是如何呢?我的链接看起来像什么? 设置会话变量应如下所示: 简而言之:单击HTML中的链接时,必须设置会话变量。 我该怎么做? PS:我对Ajax不太熟悉,但是我会赶上。 编辑:链接将指向同一页面,我也想避免类似“ home.php

  • 问题内容: 在后台代码中,我设置了一些数据。 问题是如何在javascript中获取会话值(在我的示例中为“示例数据”)并设置一个新值? 问题答案: 使用Java脚本访问和分配会话变量: 使用Javascript分配ASP.NET会话变量: 使用Javascript访问ASP.NET Session变量:

  • 你好,朋友,一个新手问题。我是编程新手,所以请温柔一点。 我试图使用JavaScript发布多个会话变量,这样我就可以在以后的PHP中的多个地方使用它们。 我的index.php文件 我的vals.js文件 我的session.php档案 我知道代码很乱,但我不知道如何编写正确的语法。我实际上试图修改一个变量代码,但失败了。因此需要帮助。 其思想是将从各种JavaScript函数派生的各种值发布到

  • 问题内容: 如何在PHP中设置会话生存期?我希望将其设置为永久,只要该请求存在。该请求是AJAX。我处理AJAX请求的PHP代码是: 和JavaScript: 该会话始终在300秒后重置。 问题答案: PHP上的会话与Cookie类型的会话一起使用,而在服务器端,会话信息会不断删除。 要在php中设置时间,可以在session_start之前使用session_set_cookie_params

  • 我需要向API服务发送一个post请求,该服务需要一个会话id以及post请求字段中的其他参数,以便获得所需的信息。 我正在使用邮递员来测试这个API。 我想知道在使用Postman时,如何在帖子请求中发送“会话ID”? 我知道Postman中的预请求脚本,但我不知道如何在post请求中使用该变量。