当前位置: 首页 > 面试题库 >

Java线程安全数据库连接

龙星辰
2023-03-14
问题内容

我正在编写一个Servlet,该Servlet通过访问和修改数据库中的某些表来处理每个请求。我希望与数据库的连接是线程安全的。我不想为此使用已经存在的库/框架(spring,hibernate等)。

我知道我可以通过以下方式为此使用java的ThreadLocal:

public class DatabaseRegistry { //assume it's a singleton


    private Properties prop = new Properties();

    public static final ThreadLocal<Connection> threadConnection = new ThreadLocal<Connection>();

    private Connection connect() throws SQLException {
        try {
            // This will load the MySQL driver, each DB has its own driver
            Class.forName("com.mysql.jdbc.Driver");
            // Setup the connection with the DB
            Connection connection = DriverManager
                    .getConnection("jdbc:mysql://" + prop.getProperty("hostname") + "/" + prop.getProperty("database") + "?"
                            + "user=" + prop.getProperty("username") + "&password=" + prop.getProperty("password"));
            return connection;
        } catch (SQLException e) {          
            throw e;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        return null;

    }

    public Connection getConnection() throws SQLException {

        if (threadConnection.get() == null) {
            Connection connection = connect();
            threadConnection.set(connection);
            return threadConnection.get();
        } else {
            return threadConnection.get();
        }
    }

    private void freeConnection(Connection connection) throws SQLException {
        connection.close();
        threadConnection.remove();
    }
}

每次调用时getConnection(),新连接都会添加到ThreadLocal对象中,然后在释放连接时将其删除。

这是这样做的正确方法,还是DatabaseRegistry它本身应该扩展ThreadLocal<Connection>类?还是有一种更好的方法来使所有连接线程安全?


问题答案:

我不认为使数据库连接具有线程安全性是常见的做法。通常您想要的是:

  • 序列化对servlet某个部分的访问,以便一次执行代码的servlet不超过一个(例如,实现SingleThreadModel接口)。
  • 锁定特定的表/表页面/行,以便您可以对某些特定的元组进行操作(通过更改数据库隔离级别)。
  • 使用乐观锁定来检测表中的修改行(使用表的某些引用属性来检查当前版本是否与表中的版本相同)。

AFAIK的典型用法ThreadLocal<Connection>是为每个线程存储一个唯一的数据库连接,以便可以在业务逻辑中的不同方法中使用相同的连接,而不必每次都将其作为参数传递。因为公共servlet容器实现使用线程来满足HTTP请求,所以保证了两个不同的请求使用两个不同的数据库连接。



 类似资料:
  • 问题内容: 我从一个非常简单的多线程示例开始。我试图做一个线程安全的计数器。我想创建两个线程,使计数器间歇地增加到1000。以下代码: 据我所知,while循环现在意味着只有第一个线程才能访问计数器,直到达到1000。输出: 我该如何解决?如何获得共享计数器的线程? 问题答案: 两个线程都可以访问您的变量。 您看到的现象称为线程饥饿。输入代码的受保护部分后(很抱歉,我之前错过了它),其他线程将需要

  • 问题内容: 我经常听到对Swing库中缺乏线程安全性的批评。但是,我不确定自己将在自己的代码中执行的操作会导致问题: 在什么情况下,Swing不是线程安全的事实起作用? 我应该积极避免做什么? 问题答案: 切勿执行长时间运行的任务以响应按钮,事件等,因为这些事件在事件线程上。如果您阻止事件线程,则整个GUI将完全无响应,从而使用户感到非常生气。这就是为什么Swing看起来缓慢又硬朗。 使用线程,执

  • 问题内容: 我目前正在为我教会的大学团体使用一个网站,并且开始对我所写内容的安全性有些担心。例如,我使用以下功能: 每当我进行某种查询时就连接到数据库。我总是使用PDO准备好的语句来防止任何用户输入的SQL注入,并且我使用htmlspecialchars进行转义,然后再输出。我的问题是: 如何保护数据库的用户名和密码? 我不知道是否有人可以查看我的PHP文件的源,但如果可以,我只能想象我会被缠住。

  • 我找到了关于线程安全的代码,但它没有来自给出示例的人的任何解释。我想知道为什么如果我不在“count”之前设置“synchronized”变量,那么count值将是非原子的(总是=200是期望的结果)。谢谢

  • 问题内容: 我需要一个线程安全映射,我有类似这样的内容:(我对Java很陌生) 问题答案:

  • 问题内容: 我有一个函数,该函数使用和来搜索字符串列表中的模式。 此函数用于多个线程。每个线程将在创建线程时传递给的唯一模式。线程和模式的数量是动态的,这意味着我可以在配置期间添加更多s和线程。 如果使用正则表达式,是否需要在此函数上放一个?Java线程中的正则表达式安全吗? 问题答案: 是的 ,来自Pattern类的Java API文档 此类(模式)的实例是不可变的,可以安全地由多个并发线程使用