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 EscalationPage Lock 以强制行锁定。

然而,这样做是有后果的。

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

【讨论】:

以上是关于SqlServer JDBC 行锁的主要内容,如果未能解决你的问题,请参考以下文章

怎么连接sql server数据库

sqlserve复制

关于sqlserve2000和sqlserver2005以后版本配置连接池的一些思路

[MSSQL]SQLServer之数据库行锁

sqlserve条件增加看不到的方法

一般问题处理记录(SqlServe)