我看到了很多有关避免阻塞的信息。我的情况是我想阻止。
我们有此表,两个单独的进程将使用该表相互通信。这些进程将在随机时间运行,并将使用此控制表来了解其他进程是否繁忙。两个进程不能同时忙,因此控制表。
每个作业在运行时都将检查控制表...,并根据该数据来决定是否可以运行,如果可以,则将更新控制表记录。
问题是,如果两个进程同时运行,则不清楚它们是否将不执行以下不希望的操作(按此确切顺序):
<-在这种情况下,两个进程都认为他们已成功更新了控制表,并将开始其主流程(这不是我们想要的)
我在这里想要的是要从控制表中选择(而不是仅更新)阻止ProcB。这样,如果/当Proc B的选择查询最终起作用时,它将看到更新的“忙”值,而不是Proc A更改之前已存在的值。
我相信我们正在使用SQL Server 2008 R2。我检查了SERIALIZABLE隔离,但是它似乎不够坚固。
为了值得的是,我们尝试使用JDBC完成此操作... conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
我们知道这是最高的隔离级别,但是我仍然可以从另一个窗口全天运行select。
我100%确信这绝不是一个独特的问题。...有人对此工作有任何建议吗?
您的方法可行,但是需要考虑以下几点:
您需要在开始时(在第一次读取之前)打开一个事务,并且必须在完成工作后才提交它。
如果A和B都尝试读取/修改相同的记录,即使使用默认的事务隔离级别(READ COMMITTED),该操作也将立即可用。否则,您需要告诉SQL Server锁定整个表(使用TABLOCK
提示)。
实际上,您根本不需要读取!
它是这样工作的:
P1 P2
---------------------------------
BEGIN TRANS
BEGIN TRANS
WRITE (success)
WRITE (blocked)
do work |
. |
. |
COMMIT -> block released, WRITE finishes
do work
.
.
COMMIT
PS:但是请注意,SQL Server支持应用程序锁。因此,如果您只想同步两个进程,则无需“滥用”表:
PPS:为完整起见,让我也回答标题中的问题(“如何在SQL Server上强制执行SELECT阻止?”):为此,可以结合使用HOLDLOCK
和XLOCK
表提示(或者TABLOCKX
,如果要独占使用,锁定整个表格)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句