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

从java.sql.Connection创建线程安全MyBatis会话

靳涵亮
2023-03-14

我正在尝试使用MyBatis和一个雪花数据库。我的情况和这张海报差不多:

配置mybatis以使用现有连接

本质上,我可以获得java.sql.Connection对象,但无法通过DataSource或Oracle等RDBMS数据库通常执行的其他步骤获得该对象。一个建议的解决方案是这样做:

SqlSession snowflakeSession = snowflakeSqlSessionFactory.openSession(getSnowflakeConnection());

这些将在多线程环境中。如果有人关闭了SnowflakesSession对象,那么是否关闭了底层java.sql.Connection对象?我计划重用这些会话,但只在一个线程内。这有必要吗?

对于甲骨文,我可以这样做:

        OracleDataSource result = new OracleDataSource();
        Class.forName("oracle.jdbc.driver.OracleDriver");
        String connectionString = jdbcUrl;
        String username = jdbcUserName; 
        String password = jdbcPassword;
        OracleDataSource oracleDataSource = (OracleDataSource)result; 
        oracleDataSource.setURL(connectionString);
        oracleDataSource.setPassword(password);
        oracleDataSource.setUser(username);
        String timeoutKey = "oracle.jdbc.ReadTimeout";
        Properties connectionProperties;
        try {
            connectionProperties = oracleDataSource.getConnectionProperties();
            if(connectionProperties==null) {
                connectionProperties = new Properties();
            }
            connectionProperties.put(timeoutKey, 60 /* minutes */ * 60 /* seconds per minutes */ * 1000 /* ms per seconds */);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return result;

如果可以创建SnowflakeDataSource对象,就可以轻松地以与Oracle相同的方式创建连接。我必须小心如何创建连接,因为这也是MyBatis扫描XML映射器文件的一点,或者重新使用它从先前的连接请求中找到的内容。

共有1个答案

马哲
2023-03-14

它似乎没有文档化,但Snowflake的JDBC驱动程序包提供了一个基本的DataSource类,当调用DataSource::GetConnection()时,它可以获取全新的连接对象:

import net.snowflake.client.jdbc.SnowflakeBasicDataSource;

SnowflakeBasicDataSource ds = new SnowflakeBasicDataSource();

ds.setUrl("jdbc:snowflake://account.region.snowflakecomputing.com/");

ds.setUser("user");
ds.setPassword("password");
ds.setWarehouse("wh");
ds.setDatabaseName("db");
ds.setSchema("schema");
ds.setRole("role");

// Other arbitrary connection or session properties can be passed
// via URL params in the ds.setUrl(...) call above

// Use ds.setOauthToken(...)
// or  ds.setAuthenticator(...)
// or  ds.setPrivateKey(...)
// or  ds.setPrivateKeyFile(...)
// for alternative modes of authentication

Connection conn = ds.getConnection();
 类似资料:
  • 问题内容: 我知道会话不是线程安全的。我的第一个问题:将实体传递给另一个线程,对它做一些工作,然后将其传递回原始线程并进行更新,是否安全? 我的第二个问题:在一个线程中创建一个实体并将其保存在另一个线程中是否安全? 编辑 我忘了提到实体是为快速加载而专门配置的 问题答案: 否。该实体已附加到会话中,并包含链接到该会话的代理(以延迟自身加载)。因此,这样做将使用多个线程中的会话。由于会话不是线程安全

  • 我有一个在Oracle 11g DB上运行的insert语句,如下所示: 这里有一个处理PostgreSQL的类似问题。但是,由于Oracle序列由所有会话共享,所以我不能相信DB会给出当前会话中最后插入的值。

  • 问题内容: 我需要知道,hibernate的会话是否是线程安全的。但是很明显,新会话将附加到每个线程以执行。但是我的问题是,如果在一个线程中我已经更新了某个实体的某个值,那么这将在同一时间执行期间反映在另一个线程中吗? 我的问题是,当我依次从两个线程启动更新时,值会正确更新,但是当我几乎完全启动更新时,它将失败。 例如 表的当前阶段。 我正在尝试以下: 当我尝试在循环中运行上述代码(例如10)时,

  • 我有一个service方法,其中我通过ID从数据库请求一个实体。如果实体具有属性,我将其设置为true并执行某些操作。如果它只返回。 现在,如果同时有多个具有相同的请求,则该方法将不再一致,因为例如,第一个请求使用接收,因此它会做“一些事情”,如果第二个请求在第一个请求使用保存费用之前来到该方法,则即使第一个请求已经保存了费用,它也会做“一些事情”。这是一个正确的结论吗? 为了确保一次只能有一个请

  • 问题内容: 我正在Tomcat上运行Web应用程序。我有一个处理所有数据库查询的类。此类包含返回查询结果的对象和方法。 这是连接对象: 它只有一个实例(单例)。 另外,我还有执行查询的方法,例如在db中搜索用户: 此方法使用静态对象。我的问题是,我在静态对象线程中使用安全吗?还是在许多用户调用该方法时会引起问题? 问题答案: 这样,连接将在所有用户发送的所有请求之间共享,因此所有查询将相互干扰。但