多线程环境下重用ResultSet成员变量

Posted

技术标签:

【中文标题】多线程环境下重用ResultSet成员变量【英文标题】:Reuse of ResultSet member variable in a multi-threaded environment 【发布时间】:2012-09-13 21:54:58 【问题描述】:

我正在实现一个使用 JDBC 驱动程序的代码。

下面是我写的代码。

public class mysqlUtils 
    public Connection conn;
    public ResultSet rs;
    public PreparedStatement stmt;

    public MysqlUtils(String address, String id, String passwd) 
        try 
            conn = DriverManager.getConnection(address, id, passwd);
            stmt = null;
            rs = null;
         catch (SQLException e) 
            // error management
        
    

    public void getSomeData(long id) 
        try 
            stmt = conn.prepareStatement("SELECT * FROM some_table");
            rs = stmt.executeQuery();
            rs.next();
            System.out.println(rs.getString("some_column");
         catch (SQLException e) 
            // error management
        
    

我已将 Connection conn、ResultSet rs、PreparedStatement stmt 声明为成员变量,因为我认为这可能有助于提高性能。

我有几个问题。

    如果我连续调用 getSomeData(),stmt 和 rs 每次都会被分配新的对象吗?

    不管上面问题的答案如何,如果我在多线程环境(使用MysqlUtils类的多线程)中运行这段代码,会不会因为我没有在其中声明ResultSet rs getSomeData()?

    将 Connection conn、ResultSet rs、PreparedStatement stmt 声明为成员变量是一个错误的选择吗?换句话说,我的 JDBC 实现是否可行?

感谢您的帮助。

【问题讨论】:

你应该填写List<T> ...或将数据传递到线程池进行处理,只有一个线程读取 ResultSet。 【参考方案1】:
    是的。该方法将被执行,因此stmtrs 将采用新值。当然,您的类可能有多个实例,因此这两个字段也有多个实例。 是的。这段代码是完全线程-*un*安全的。一般来说,公共领域几乎总是应该避免的。尤其是在多线程环境中 是的,这是一个糟糕的选择。变量的范围应尽可能小。并且这些变量在单个方法中使用,并且每次都重新分配。它们应该是局部变量。

还有:

方法getSomeData() 应该返回一些东西,而不仅仅是打印一些东西 ResultSet 和 Statement 应在 finally 块中关闭 我希望错误管理不在于吞下异常

我建议使用 spring-jdbc,它会为您处理所有管道代码,并避免您的代码当前存在的所有问题。

【讨论】:

我现在正在查看 Spring JDBC 模板。这对我来说是一个全新的世界。感谢您的提示!【参考方案2】:

不要在方法之外使用 ResultSet.... 使用 while(rs.next) (rs=resultSet) 您正在循环访问数据库表并检索值!

【讨论】:

以上是关于多线程环境下重用ResultSet成员变量的主要内容,如果未能解决你的问题,请参考以下文章

多线程访问全局变量和局部变量

Spring 单例 多例 线程安全等问题,想请教大家

Java 多线程 多线程访问成员变量与局部变量

JAVA多线程并发问题

多线程访问成员变量与局部变量

如何证明Java多线程中的成员变量的值是互不可见的