SqlServer JDBC RowLock

时间:2016-09-20 08:41:46

标签: java sql-server sql-server-2008 jdbc

这是我的问题:

我在表格中列出了IDS。多个任务同时需要读取一些IDS,使用该ID检索一些其他数据并写入一些文件。 每个任务必须在不同的IDS上工作。 显然,如果出现问题,我必须回滚以允许其他任务再次尝试写入文件。

我使用Java 1.8(Spring Boot Framework)和SQLServer 2008 R2与Microsoft JDBC Driver 4.1。

在我的解决方案中,每个任务都会打开一个事务,并通过使用ROWLOCK执行更新来锁定要处理的记录

DefaultTransactionDefinition dtd = new DefaultTransactionDefinition();
dtd.setIsolationLevel(DefaultTransactionDefinition.ISOLATION_READ_COMMITTED);
dtd.setName(taskName);
TransactionStatus ts =transactionManager.getTransaction(dtd);

List<Long> result = jdbc.query("select top 3 * from D_TEST where STATUS = 0 order by 1",new LongExtractor());

for(Long l:result){
        jdbc.update("update D_TEST with  (ROWLOCK) set STATUS = 1 where ID_ROW = "+l.toString());
}

然后它使用IDS列表执行其他任务,如果一切正常,关闭事务,否则回滚。

我希望如果另一个任务开始,而第一个任务仍在运行,当它要求提供一组IDS时,它将不会收到锁定的任务。

问题是查询锁定整个表而不仅是行。 我的错误在哪里?我怎么才能锁定一些行呢?

有人建议(SQL Server - Row Lock with JDBC)将隔离级别更改为ISOLATION_READ_UNCOMMITTED,但在这种情况下,我还会读取第一个任务正在更新的记录。 此外,使用此隔离级别,第二个任务仍然停止等待它结束的第一个事务。

1 个答案:

答案 0 :(得分:0)

据我所知,之前已完成此操作,您必须在SqlServer中的索引上禁用 Lock Escalation Page Lock 以强制执行一行锁。

然而,这样做会产生后果。

以下是link供您参考。 希望这会有所帮助。