Java JDBC事务如何在事务\读取\提交隔离级别中锁定表?

Java JDBC事务如何在事务\读取\提交隔离级别中锁定表?,java,jdbc,locking,database,Java,Jdbc,Locking,Database,我读过这篇教程:但我觉得我仍然缺少一些东西 让我们举一个例子: 线程T1有自己的连接 线程T2有自己的连接 因此,这些线程在两个不同的连接上执行一个事务(setAutoCommit(false))。此事务在单个DB表上执行以下查询: 选择一行以读取累进编号(PN) 插入一行,将累进数设置为:PN++(我所做的 阅读+1) 此表中的累进编号必须是唯一的(它是主键) JDBC事务(具有事务读取提交隔离级别)是否避免了T1和T2读取相同的PN值并尝试在表中插入相同的PN++的问题?在执行插入并

我读过这篇教程:但我觉得我仍然缺少一些东西

让我们举一个例子:

  • 线程T1有自己的连接
  • 线程T2有自己的连接
因此,这些线程在两个不同的连接上执行一个事务(setAutoCommit(false))。此事务在单个DB表上执行以下查询:

  • 选择一行以读取累进编号(PN)
  • 插入一行,将累进数设置为:PN++(我所做的
    阅读+1)
此表中的累进编号必须是唯一的(它是主键)


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

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

事务_READ _COMMITTED将只确保您只能读取已提交到DB的数据。也就是说,如果您的

UPDATE sequence 


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

您也可以在应用程序级别进行同步。如果一个应用程序中只有一个方法在执行增量操作,那么这将是可行的

private **synchronized** void increment() {
    Calendar calendar = Calendar.getInstance();
    int year = calendar.get(Calendar.YEAR);
    int current = dao.getMaxNumber(year);
    dao.insertNumber(year, current+1);
}

问题是,在我的例子中,主键也是由其他两个字段(年和月)组成的,而不仅仅是累进数,累进数必须是唯一的,然后,在一年中的一个月内,从零开始另一个月。因此,我担心在读取、递增、更新期间锁定行可能是唯一的方法。
private **synchronized** void increment() {
    Calendar calendar = Calendar.getInstance();
    int year = calendar.get(Calendar.YEAR);
    int current = dao.getMaxNumber(year);
    dao.insertNumber(year, current+1);
}