我有2个批程序、1是一个程序,发送电子邮件和一个又一个发送传真。他们两人访问表名为 QUEUE.

在电子邮件发送者的程序,这是发生了什么有关 QUEUE.每个记录在 QUEUE 满足标准:

  1. 锁记录在1 QUEUE 表:
    select 1 from QUEUE with (UPDLOCK) where id = 1
  2. 过程中发出的电子邮件
  3. 删除记录的1在队列中的表:
    delete from QUEUE where id = 1
  4. 提交事务(交易不是自动提交)

在传真发送者的程序,类似的步骤也会发生这种情况,除了在第2步,我们发出的传真(当然)。

问题是,有时候删除 QUEUE 抛出了一个例外,它被锁定。因此,重新发送的电子邮件/传真发生。我相信,该小组的记录,处理通过这些程序不相交叉。

它似乎删除试图获得一个更新(U)锁定在其他记录表虽然只有一个记录被删除。因此例外情况发生时其他交易都有锁上的其他记录中,同样表。

我需要知道如果有一个选项,以使"删除"操作不能取得锁上记录的其他比的记录,它将删除。因为它似乎是问题的"删除"操作把门锁上的其他记录表中。

顺便说一下,这里是一些关信息的数据库(我不知道如果他们将帮助):

  • 读提交的快照是打开
  • 快照隔离状态是在
有帮助吗?

解决方案

你有没有尝试过使用与ROWLOCK或与NOLOCK提示上删除的声明吗?

你有没有读 这篇文章?它建议您使用(UPDLOCK,READPAST),以防止该问题遇到你

其他提示

有时候,锁escalades从锁定一个单一的行为锁定的一部分表或锁定整个表。这是最有可能为什么你们得锁上记录的,你是不是实际使用的交易。

而不是使用事务锁的记录,可以使用一个状态场标志的记录,是处理。

例如:

锁定一些记录,然后得到的记录是成功锁定:

update queue set status = 'email_processing' where status is null and id = 1
select email, message from queue where status = 'email_processing'

当你是不是明确地使用了交易各个查询的运行在它自己的事务,因此更新的查询可以安全地改变状况,因为它的验证当前状况相同的查询。

当完成后送,删除记录:

delete from queue where status = 'email_processing'

传真发送人当然会使用不同的状况(如'fax_processing')使标记的记录是孤立的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top