JDBC Transaction如何在TRANSACTION_READ_COMMITTED隔离级别锁定表?

时间:2012-07-19 11:18:33

标签: java jdbc locking database

我已阅读本教程:http://docs.oracle.com/javase/tutorial/jdbc/basics/transactions.html但我认为我仍然缺少某些内容。

让我们举一个例子:

  • 线程T1有自己的连接
  • 线程T2有自己的连接

因此,这些Threads在两个不同的Connections上执行Transaction(setAutoCommit(false))。此事务在单个数据库表上执行以下查询:

  • 选择一行以读取渐进数字(PN)
  • 插入一行,将渐进编号设置为:PN ++(我已经完成了 读+1)

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

JDBC事务(具有TRANSACTION_READ_COMMITTED隔离级别)是否避免了T1和T2读取相同PN值的问题,并且两者都试图在表中插入相同的PN ++?在执行Insert并调用commit()之前,表是否已锁定?

2 个答案:

答案 0 :(得分:1)

不,为了确保您始终拥有唯一号码,您需要: 1)[更好]根据DB将DB字段更改为identity / sequence / auto-number 2)使用UUID作为标识符 3)[最差]在读取/递增/写入序列的持续时间内锁定行

TRANSACTION_READ_COMMITTED只会确保您只能读取已提交给DB的数据。即如果你的

之间有另外200个数据库操作
UPDATE sequence 

commit

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

答案 1 :(得分: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);
}