对于长时间运行的插入,我想要哪个SQL Read TRANSACTION ISOLATION LEVEL?

时间:2008-10-30 22:15:07

标签: sql-server-2005 performance transactions

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

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

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

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

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

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

谢谢你,
基思

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

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

2 个答案:

答案 0 :(得分:2)

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

修改

您可以在一个事务中包装MainTable更新,以便更快地释放该表,但您仍可能与其他表发生冲突。

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

答案 1 :(得分:0)

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

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED