1

我有一个长时间运行的插入事务,它将数据插入到几个相关的表中。

当此插入运行时,我无法从 MainTable 执行 select *。选择只是旋转它的轮子,直到插入完成。

我将在相同/重叠的时间执行其中几个插入。为了检查信息是否没有插入两次,我首先查询 MainTable 以查看是否存在条目并且未设置其处理位。

在插入事务期间,它翻转该行的 MainTable 处理位。

所以我需要能够读取表格,并且能够判断特定行当前是否正在更新。

关于如何在 Microsoft SQL 2005 中进行设置的任何想法?我正在查看SET TRANSACTION ISOLATION LEVEL文档。

谢谢你,
基思

编辑: 我不认为相同的插入批次会同时发生。这些是正在处理的二进制文件,它们的数据插入到数据库中。在解析和插入数据之前,我检查文件是否未被处理。当我进行检查时,如果在我快速插入 MainTable 之前没有看到该文件,并且已处理的位设置为 false。

有没有办法锁定正在更新的行而不是整个表?

4

2 回答 2

2

在使用 READ UNCOMMITTED 之前,您可能需要重新考虑您的流程。隔离交易有很多很好的理由。如果您使用 READ UNCOMMITTED 您可能仍然会得到重复,因为两个插入有可能同时检查更新并且都没有发现它们创建重复。尝试将其分成更小的批次或发出定期 COMMITS

编辑

您可以将 MainTable 更新包装在可以更快释放该表的事务中,但您仍然可能会与其他表发生冲突。

IE

BEGIN TRANSACTION

SELECT @ProcessedBit = ProcessedBit FROM MainTable WHERE ID = XXX

IF  @ProcessedBit = False
    UPDATE MainTable SET ProcessedBit = True WHERE ID = XXX

COMMIT TRANSACTION

IF  @ProcessedBit = False
BEGIN
    BEGIN TRANSACTION
    -- start long running process
    ...
    COMMIT TRANSACTION
END

编辑以启用错误恢复

BEGIN TRANSACTION

SELECT @ProcessedStatus = ProcessedStatus FROM MainTable WHERE ID = XXX

IF  @ProcessedStatus = 'Not Processed'
    UPDATE MainTable SET ProcessedBit = 'Processing' WHERE ID = XXX

COMMIT TRANSACTION

IF  @ProcessedStatus = 'Not Processed'
BEGIN
    BEGIN TRANSACTION
    -- start long running process
    ...

   IF No Errors
   BEGIN
       UPDATE MainTable SET ProcessedStatus = 'Processed' WHERE ID = XXX
       COMMIT TRANSACTION
   ELSE
       ROLLBACK TRANSACTION

END
于 2008-10-30T22:42:27.233 回答
0

允许一个事务读取由另一个正在进行的事务(在它提交之前)执行的更改的唯一隔离级别是:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
于 2008-10-30T22:35:22.333 回答