0

我已经阅读了本教程:http ://docs.oracle.com/javase/tutorial/jdbc/basics/transactions.html但我认为我仍然缺少一些东西。

让我们举个例子:

  • 线程 T1 有自己的 Connection
  • 线程 T2 有自己的 Connection

因此,这些线程执行一个事务(setAutoCommit(false) 在两个不同的连接上)。此事务在单个数据库表上执行以下查询:

  • 选择一行以读取累进数字 (PN)
  • 插入一行将渐进数设置为:PN++(我
    读过的内容+1)

此表中的累进数字必须是唯一的(它是主键)。

JDBC Transactions(带有 TRANSACTION_READ_COMMITTED 隔离级别)是否避免了 T1 和 T2 读取相同的 PN 值并尝试在表中插入相同的 PN++ 的问题?在执行插入并调用 commit() 之前,表是否被锁定?

4

2 回答 2

1

不,为了确保您始终拥有唯一编号,您需要:1) [更好] 将 DB 字段更改为身份/序列/自动编号,具体取决于 DB 2) 使用 UUID 作为标识符 3) [最差] 锁定读取/递增/写入序列持续时间的行

TRANSACTION_READ_COMMITTED 只会确保您只能读取已经提交到数据库的数据。即,如果您之间还有 200 个数据库操作

UPDATE sequence 

commit

在您提交之前,其他线程将无法读取您更新的数据,因此实际上它会做与您想要的完全相反的事情。

于 2012-07-19T11:35:25.563 回答
0

您还可以在应用程序级别进行同步。如果一个应用程序中只有一种方法正在执行增量,这将起作用。

private **synchronized** void increment() {
    Calendar calendar = Calendar.getInstance();
    int year = calendar.get(Calendar.YEAR);
    int current = dao.getMaxNumber(year);
    dao.insertNumber(year, current+1);
}
于 2013-09-04T08:05:07.333 回答