这是我的问题:
我在表格中列出了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
,但在这种情况下,我还会读取第一个任务正在更新的记录。
此外,使用此隔离级别,第二个任务仍然停止等待它结束的第一个事务。
答案 0 :(得分:0)
据我所知,之前已完成此操作,您必须在SqlServer中的索引上禁用 Lock Escalation 和 Page Lock 以强制执行一行锁。
然而,这样做会产生后果。
以下是link供您参考。 希望这会有所帮助。