SqlServer JDBC 行锁
Posted
技术标签:
【中文标题】SqlServer JDBC 行锁【英文标题】:SqlServer JDBC RowLock 【发布时间】:2016-09-20 08:41:45 【问题描述】:这是我的问题:
我在表格中有一个 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
,但在这种情况下,我还阅读了第一个任务正在更新的记录。
此外,在这种隔离级别下,第二个任务仍然会停止等待它结束的第一个事务。
【问题讨论】:
我敢打赌 order by 会导致表锁定,即使您要求的是前 3 条记录;是否有关于它的排序依据的索引? 【参考方案1】:据我所知,之前做过,您必须在 SqlServer 中的索引上同时禁用 Lock Escalation 和 Page Lock 以强制行锁定。
然而,这样做是有后果的。
这里是link 供您参考。 希望这会有所帮助。
【讨论】:
以上是关于SqlServer JDBC 行锁的主要内容,如果未能解决你的问题,请参考以下文章