java - 多线程环境中的 JDBC 事务

标签 java multithreading jdbc transactions

开发Java应用,多线程共享同一个Connection,会出现并发问题。

如果线程 A 更新表 T 中的记录 1,同时线程 B 对表 T 中的记录 1 发出 SELECT,我如何确保线程 B 读取线程 A 的更新值?

java.sql.Connection 提供带有 begin()、commit() 和 rollback() 的事务,但是这个过程是否也包括数据正确性?

我想我错过了什么。

最佳答案

两点:

  1. 您不应该在线程之间共享一个jdbc.Connection,至少对于任何“认真生产”的代码,请参见here .出于演示目的,我认为共享一个连接是可以的;
  2. 如果一个线程在提交相关数据库事务后从数据库读取,它将看到另一个线程写入的数据。

第二个问题

will thread B timeout until the first transaction has commit() or rollback()

-- B 将阻塞直到 A tx 完成(通过提交或回滚),如果:

  1. B 尝试更新/删除 A 正在更新的同一表行,并且...
  2. A 使用 SELECT ... FOR UPDATE 在 DB 级锁定下更新该行。

您可以使用两个控制台(例如,使用 PostgreSQL psql)获得此行为,每个控制台代表一个线程:

A 控制台中输入以下内容:

BEGIN;
SELECT some_col FROM some_tbl WHERE some_col = some_val FOR UPDATE;

现在在 B 控制台类型:

BEGIN;
UPDATE some_tbl SET some_col = new_val WHERE some_col = some_val;

您应该看到 UPDATE 一直阻塞,直到您在 A 中执行了 COMMITROLLBACK

上面的解释使用了单独的DB连接,就像Java JDBC连接池一样。我认为,当您在 Java 线程之间共享单个连接时,如果连接被其他线程使用,与 DB 的任何交互都会被阻塞。

关于java - 多线程环境中的 JDBC 事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46217941/

相关文章:

java - 在 Ratpack 中的 Blocking.get 中返回一个值

java - 使用使用 Runnable 的线程和派生的 Thread 类之间的行为存在意外差异

java - 当 mysql-connector-java-8.0.16.jar 位于类路径中时,为什么会收到 java.lang.ClassNotFoundException : com. mysql.cj.jdbc.Driver?

java - 如何通过os认证连接oracle数据库?

MySQL JDBC 驱动程序无法创建带有连字符的模式

java - 如何在 ItemTouchHelpers 中的某个点停止滑动?

java - 如何在终端中访问 Java 属性

java - 如何强制 Eclipse 将 java 项目视为 java 项目?

c - sem_post 不会优先考虑其他线程中的 sem_wait 调用

multithreading - 在Linux/UNIX上的多处理情况下是否可以使用互斥锁?