使用哪种隔离级别来防止数据被读取?

时间:2010-10-15 15:51:46

标签: c# .net sql-server transactions isolation-level

我有这样的情况。

查询就是这样。

Select * from TABLE where ID = 1

(什么是查询:)

之后,我更改了该行中的内容并使用新的id插入它。

我想阻止其他查询从查询中读取第一个原始行,直到我完成读取和插入。在那之后..前进。

基本上我希望select和insert在事务中,隔离级别将阻止从该行读取,直到插入完成。

OleDbTransaction正在播放,因为我使用SQL Server 6.5(哦,是的,你读得对,不要问为什么:)

我正在挖掘隔离级别描述,但是不能完全理解它们并为我的问题找到解决方案,所以我的问题是用于OleDbTransaction的隔离级别?

希望我很清楚:)

感谢。

3 个答案:

答案 0 :(得分:5)

您必须持有锁定交易的持续时间。也是专属。

现在,我不确定SQL Server 6.5的正确选项。从那以后,没有使用它,呃,199x

BEGIN TRAN

--edit, changed to XLOCK, ROWLOCK, HOLDLOCK
SELECT * from TABLE WITH (XLOCK, ROWLOCK, HOLDLOCK) where ID = 1
...
INSERT

COMMIT

编辑:

我的更改旨在将单行(精细粒度)锁定到结尾 交易。

但是,IIRC ROWLOCK添加了SQL Server 7和6.5只是页锁。但已经有一段时间了。我当时有头发和牙齿: - )

答案 1 :(得分:0)

描述的情况称为Phantom Read。所以你需要Serializable Isolation(SERIALIZABLE

答案 2 :(得分:-1)

您需要锁定行:在读取行之前创建锁定,并在更新行之后释放锁定。

Oracle 和类似数据库中,读取不会锁定,因此您需要执行以下操作(在事务中):

SELECT * FROM table WHERE id=? FOR UPDATE
...
UPDATE table ....

MS SQL 中,我不太确定,最简单的方法是尝试以下方法:打开两个连接到数据库的窗口,在两者中启动一个事务,执行SELECT,然后看看你是否可以从第二个选择。如果语句没有返回,那意味着该行被锁定并且你很好。

我认为,在您的问题中,您的意思是在选择行后更新,而不是插入它(插入会创建一个新行,更新会更改现有的行)