这会阻止在交易期间读取行吗?

时间:2010-04-13 03:19:12

标签: sql concurrency

我记得一个例子,其中读取事务然后写回数据是不安全的,因为另一个事务可能在它之间读/写它。所以我想检查日期并防止行被修改或读取,直到我的交易完成。这会诀窍吗?是否有任何sql变种,这将不起作用?

update tbl set id=id where date>expire_date and id=@id

注意:日期> expire_date恰好是我的条件。它可能是任何东西。这会阻止其他事务在我提交或回滚之前读取行吗?

4 个答案:

答案 0 :(得分:1)

这取决于您在事务控件上设置的事务隔离级别。有4种类型的读取

READ UNCOMMITTED: this allows the dirty read
READ COMMITTED 
REPEATABLE READ
SERIALIZABLE

了解更多信息,您可以查看msdn。

答案 1 :(得分:1)

您应该可以使用

的组合在正常选择中执行此操作

HOLDLOCK/ROWLOCK

答案 2 :(得分:1)

很可能会奏效。不同平台提供不同的服务。例如,在T-SQL中,您可以简单地设置事务的隔离级别,从而强制获取锁定。我不知道你正在使用什么平台,所以我无法明确地回答你的问题。

答案 3 :(得分:1)

在很多情况下,您的UPDATE语句不会阻止其他事务读取该行。

ziang提到了事务隔离级别。

根据隔离级别,数据库使用不同类型的锁定。在最高级别,锁定可分为两类:
- 悲观,
- 乐观

例如,MS SQL 2008有6个隔离级别,其中4个是悲观的,2个是乐观的。默认情况下,它使用READ COMMITTED隔离级别,该级别属于悲观类别。

另一方面,Oracle默认使用乐观锁定。

将锁定您的记录以进行书写的声明是

SELECT * FROM TBL WITH UPDLOCK WHERE id=@id

从那时起,没有其他交易能够使用id = @id更新您的记录 并且只有在隔离级别READ UNCOMMITTED中运行的事务才能读取它。

使用默认事务级别READ COMMITTED,在您提交或回滚整个事务之前,其他任何事务都无法读取或写入此记录。