这里回复过:
http://topic.csdn.net/u/20071207/21/506850e3-a524-4b40-b919-9c9353d61a49.html
http://topic.csdn.net/u/20071207/21/506850e3-a524-4b40-b919-9c9353d61a49.html
解决方案 »
- tsql max min 数据对应的id
- 求一个SQL查询语句,能绕弯的进
- MSSQL2005备份导出的数据能否导入到2000中使用
- SQL中关于动态查询某一列(面试题目,麻烦大家了!!!!)
- 求条查询语句!
- 两个相同结构的表如何用最简洁的语句在触发器中定义当修改表a时自动修改表b?
- 求统计数目和总和的SQL语句,首先解决或提供了解决思路的给60,其余均分。
- 紧急!没有SA密码。WINDOWS也不能验证.怎么才能登陆进去!!!
- 怎样设置datetime的格式
- 我想在sql中建立一张记录时间的数据表。。。。。。。。。?
- 如何对SQL2005可以还原的文件转换到2000里的数据库里?
- 如何在表的指定位置添加字段?
另外其实这个和顶楼描述的情况还是有些不同的,在串行隔离级别之下,所有select出来的行都会被放上锁,但是,这时即使再加上放置表级锁,也无法阻止并发的更新语句把一些原本不符合条件的行(也就是没有被select出来的行)更新为符合条件啊?这样的话,被select出来的数据集和数据源就不一致了。。
-----------------------------------------------
a) 如果UPDATE先执行,将在需要修改的记录上放排斥锁,SELECT会等到UDPATE结束之后才能执行。上面情况不会发生。
b) 如果SELECT先执行,在SELECT获得完整的结果集之前,有共享锁放在要作为返回集的纪录上,这个时候UPDATE能否执行应该看隔离级别的设置(?需要其他人确认一下)2. 更新语句令某些不符合条件的行变成符合条件
-----------------------------------------------
和上面的分析类似。而且这种情况在多个用户环境下是完全有可能发生的。
比如订票系统里面就很明显,当一个票务员搜索某个航班的时,第一次查询是没有座位。但与此同时,另外一个人退票了。那么当前面一个票务员再此查询时,就可能看到有个空位。我觉得这不是数据库放锁的问题,而是应用本身的特点,不能有死锁和很慢的响应是关键。产生这种情况的原因是这里面有两个完全不相关的事务。这和银行那种划账再取钱的一个完整事务不一样。
Specifies that:*) Statements cannot read data that has been modified but not yet committed by other transactions.*) No other transactions can modify data that has been read by the current transaction until the current transaction completes.*) Other transactions cannot insert new rows with key values that would fall in the range of keys read by any statements in the current transaction until the current transaction completes.Range locks are placed in the range of key values that match the search conditions of each statement executed in a transaction. This blocks other transactions from updating or inserting any rows that would qualify for any of the statements executed by the current transaction. This means that if any of the statements in a transaction are executed a second time, they will read the same set of rows. The range locks are held until the transaction completes. This is the most restrictive of the isolation levels because it locks entire ranges of keys and holds the locks until the transaction completes. Because concurrency is lower, use this option only when necessary. This option has the same effect as setting HOLDLOCK on all tables in all SELECT statements in a transaction.
对串行隔离级别,SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
在一个事务中select 一个表中的记录,整个表都会被锁住,事务未提交前,其它事务的update或insert,delete语句是执行不了的.如果采用排它锁,可防止其它事务读记录.
-------------------------------------------------------
呵呵,答案已经在7楼里面了,摘出来:
This blocks other transactions from updating or inserting any rows that would qualify for any of the statements executed by the current transaction. The range locks are held until the transaction completes. 如果其他的更新和插入操作涉及的记录符合当前事务的查询范围,则这些操作会被范围锁阻止,直到当前事务完成。如果LZ担心事务完成之后,又有新的更新和插入发生,并且又是之前事务的那个查询范围,那就是无法避免的。还是看4楼那个订票系统的例子。你只能保证一个事务存在时,数据的完整性得到保护。
select id from article where userid = 1000;
假如返回记录集:1,3,50,80
如果按范围锁定,那么在查询事务结束前,id从1到80的记录不能被其它事务修改,但是如果此时有一个并发事务执行:
update article set userid = 1000 where id = 81;
如果这条语句被执行,那刚才返回的记录集就出现遗漏了,因为此时多了一条符合条件的记录(大概算是不可重复读?)。
所以我觉得在条件查询时只有禁止插入、删除以及任何行的更新,才能完全保证一致性。。
select id from article where userid = 1000;
假如返回记录集:1,3,50,80
如果按范围锁定,那么在查询事务结束前,id从1到80的记录不能被其它事务修改,但是如果此时有一个并发事务执行:
----------------------------------------------
范围锁不是放在1到80之间,而是放在 userid = 1000 上面
所有符合 userid = 1000 的记录都是锁定范围。
但是我觉得只有范围锁好像还是不能保证顶楼说的那两点啊(尤其是第2点)?还是上面的例子,id为81的行如果userid!=1000,它就不会被锁,也就有可能被并发更新为userid=1000了
还是说锁的不是行而是条件?那如果一个条件查询很复杂,那效率岂不是很低了?难道还有列锁这东西?所有作为查询语句的查询条件的列都放上锁?
update article set userid = 1000 where id = 81;
这就会被范围锁阻止,不能被执行的。