2010-10-15 41 views
5

我有这样的情况。使用哪种隔离级别来防止数据被读取?

查询是这样的。

Select * from TABLE where ID = 1 

(什么是查询:)

后,我改变的东西,行,用新的ID插入。

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

基本上我想要选择并插入到事务中,隔离级别将阻止只从该行读取,直到插入完成。

OleDbTransaction是在玩,因为我使用SQL Server 6.5(哦,是的,你没有看错,不要问为什么:)

我是通过隔离级别描述挖,但不能完全理解他们,并找到解决方案对于我的问题,所以我的问题是什么隔离级别使用OleDbTransaction

希望我很清楚:)

谢谢。

回答

-1

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

甲骨文和类似的数据库,读不锁,所以你需要做的(在一个事务)以下:

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

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

我想,在你的问题,你的意思是更新行你选择后,不插入它(插入创建一个新的行,更新更改现有行)

+0

无用的答案,因为MS SQL中的基本隔离级别比Oracle更宽松 – Andrey 2010-10-15 15:59:23

+0

-1您为什么在SQL Server时回答Oracle,然后提及您不需要知道它吗? – gbn 2010-10-15 16:00:27

+0

首先,互联网上的某个人可能会遇到这个页面,并且正在使用Oracle,所以我想我可能会加入它;其次它可能在SQL Server中是类似的,所以它可能是一个指向正确方向的指针。 – 2010-10-15 16:14:13

0

描述的情形被称为Phantom Read。所以你需要串行化隔离(SERIALIZABLE

+0

为什么这是downvoted? – Andrey 2010-10-15 16:26:28

+0

首先我把这个隔离级别,然后几个人,但在任何情况下,我得到错误说,执行相同的选择查询的其他进程陷入死锁,并成为死锁的受害者,并取消。似乎这个事情与隔离水平不是我的解决方案或我做错了什么.. – 100r 2010-10-15 19:45:46

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只是页锁。但已经有一段时间了。当时我有头发和牙齿:-)

+0

我不能使用表锁。因为有时会出现一些真正的重质问题,而TABLOCKX会锁定桌面吗? – 100r 2010-10-15 16:17:53

+0

请参阅更新 – gbn 2010-10-15 16:23:24

+0

tnx。我无法使任何锁工作。查询不会编译。也许6.5 sintax是不同的。我会在星期一上班的时候试试它,感谢上帝,我没有6.5在家里:) – 100r 2010-10-15 19:39:10