Java线程安全数据库连接 [英] Java thread safe database connections

查看:112
本文介绍了Java线程安全数据库连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm writing a servlet that handles each request by accessing and modifying some table(s) in the database. I want the connections to the database to be thread safe. I don't want to use already existing libraries/frameworks for this (spring, hibernate, etc.).

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

I know I can use java's ThreadLocal for this in the following way :

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对象,然后在释放连接时将其删除。

Each time you call getConnection(), the new connection is added to the ThreadLocal object and then removed when you free the connection.

这是正确的方法吗?或者DatabaseRegistry本身是否应该扩展ThreadLocal类?或者有更好的方法来使所有连接线程安全吗?

Is this the proper way of doing this or should the DatabaseRegistry itself extend the ThreadLocal class? Or is there an even better way to do this to make all connections thread safe?

谢谢

推荐答案

我认为将数据库连接设置为线程安全并不常见。通常你想要的是:

I don't think that making database connections thread-safe is a common practice. Usually what you want is either:


  • 序列化对servlet某些部分的访问,这样只有一个servlet执行代码一次(执行 SingleThreadModel 界面)。

  • 锁定特定的表/表页/行,以便您可以对某些操作特定元组(通过更改数据库隔离级别)。

  • 使用乐观锁定检测表中的已修改行(使用表的某些引用属性检查当前版本是否与表中的那个)。

  • Serialize the access to some part of your servlet, so that there is no more than one servlet executing code at a time (ex implementing the SingleThreadModel interface).
  • Locking a particular table/table page/row so you can operate on some particular tuple (by changing the database isolation level).
  • Using optimistic locking to detect modified rows in a table (using some reference attribute of the table to check if the current version is the same that the one in the table).

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

AFAIK, the typical use of ThreadLocal is to store a unique database connection per thread, so that the same connection can be used in different methods in your business logic without the need of passing it as a parameter each time. Because the common servlet container implementation uses a thread to fullfil an HTTP request, then two different requests are garanteed to use two different database connections.

这篇关于Java线程安全数据库连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆