Java线程安全数据库连接

2023-11-29

我正在编写一个 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 请求,因此可以保证两个不同的请求使用两个不同的数据库连接。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java线程安全数据库连接 的相关文章

随机推荐

  • 文本作为 CSS 的背景图像

    我正在尝试使用 Jquery 和 CSS 将字母表中的字母 随机 显示为 div 的背景图像 但是 我希望每个元素的字母是随机的 但我只能同时对所有图像进行随机化 HTML div class randbg div div class ra
  • std::chrono::duration::count 函数的实际结果类型是什么

    实际结果类型是什么std chrono duration count函数类似于以下情况 std chrono duration cast
  • 全局命名空间中的保留名称

    从我的回答中得出C 中的动态对象数组并作为后续行动在 C 标识符中使用下划线的规则是什么 显然 名字开头 后面跟着的大写字母在全局命名空间中保留 17 4 3 2 1 全局名称 lib global names 某些名称和函数签名集始终保留
  • 如何制作通用链表

    我正在尝试在中创建一个通用链表C编程语言和我 成功了 但我有一个小问题 链接列表 h struct Element void data struct Element nEl typedef struct Element Element st
  • C#7:Out 变量中的下划线 (_) 和星号 (*)

    我正在阅读 C 7 中新的输出变量功能here 我有两个问题 It says 我们也允许 丢弃 作为输出参数 形式为 让你忽略你不关心的参数 p GetCoordinates out var x out I only care about
  • 在C#中,接口可以实例化吗?

    我正在阅读中的代码here 我发现private ITreeModel model 在 TreeList cs 中 namespace Aga Controls Tree public class TreeList ListView reg
  • 通过嵌套字典键对 pandas 数据框进行分组

    我有一个 pandas 数据框 其中一列是字典类型 这是一个示例数据框 import pandas as pd df pd DataFrame a 1 2 3 b 4 5 6 version major 7 minor 1 major 8
  • 递归循环遍历 DOM 树并删除不需要的标签?

    tags array applet gt 1 script gt 1 html file get contents test html dom new DOMdocument dom gt loadHTML html xpath new D
  • 通过常见的键值对组合 JSON

    我目前正在解决一个问题 似乎无法解决这个问题 这是一些数据 以便您了解我在下面所说的内容 foo json Schedule deviceId 123 reservationId 123456 username jdoe deviceId
  • 由于写访问权限,无法使用 Android shell atrace 命令

    如果我尝试atrace工具来自adb壳里emulator atrace atrace error opening sys kernel debug tracing options overwrite No such file or dire
  • 如何创建全局辅助函数?

    我想创建一些全局辅助函数 我知道我必须将它们放在 App Code 中的 cshtml 文件中 我创建了这个文件 helper CreatePostForm string action string controller string id
  • 使用请求登录有问题的站点

    我正在尝试使用 requests 模块在 python 中创建一个脚本来登录到此site 我正在使用我的凭据 但我找不到任何方法来这样做 因为我看不到与请求一起发送所需的参数 在 Chrome 开发工具中 username SIMMTH i
  • 如何使用Maven PDF插件从Surefire Report生成PDF?

    运行 JUnit 测试后 我使用 Maven Surefire Report 插件 http maven apache org plugins maven surefire report plugin 生成 HTML 测试报告 这会产生以下
  • Kubernetes 中的 TCP 入口支持

    似乎 TCP 和 UDP 支持将在下一版本的 ingress nginx 控制器中被弃用 还有其他入口控制器支持 TCP 和 UDP 吗 或任何其他在 kubernetes 之外公开非 http 端口的解决方案 kubernetes 初学者
  • 如何在 Excel 工作表中查找精确值

    如何在 Excel 工作表中找到字符串值 我在尝试objRange Find 但这也给了我错误的地址 例如 我想要 Object paint 的地址 但它也给出 Object paint and stk 的地址 我应该如何获得精确的值 Se
  • Spring boot war文件部署在Tomcat上

    我使用 Spring Boot 1 2 4 RELEASEGS 休息服务源文件 我有 127 0 0 1 18 Jun 2015 09 59 25 0300 GET gs rest service 0 1 0 HTTP 1 1 404 10
  • Mac OS X:_tkinter.TclError:没有显示名称,也没有 $DISPLAY 环境变量

    正如我所说 我已经从 Macports 安装了 Python 3 3 现在 当我重点搜索 空闲 时 Idle Python 3 3 出现 但是 当我尝试单击它时 什么也没有发生 没有显示任何错误或任何东西 它显然不会启动 您认为可能有什么问
  • 为什么要在数据库中创建视图?

    何时以及为何有人决定需要在数据库中创建视图 为什么不直接运行一个普通的存储过程或选择呢 视图提供了多种好处 1 视图可以隐藏复杂性 如果您的查询需要连接多个表 或者具有复杂的逻辑或计算 则可以将所有逻辑编码到视图中 然后像选择表一样从视图中
  • 移动当前可执行文件c#

    我想将当前正在执行的程序集移动到 C 驱动器 当我尝试以下代码时 File Move Assembly GetEntryAssembly Location c 它给了我一个错误 mscorlib dll 中发生 System Unautho
  • Java线程安全数据库连接

    我正在编写一个 servlet 它通过访问和修改数据库中的某些表来处理每个请求 我希望与数据库的连接是线程安全的 我不想为此使用现有的库 框架 spring hibernate 等 我知道我可以通过以下方式使用 java 的 ThreadL