select * from table with(加锁方式)
解决方案 »
- 如何将查询到的数据表导入到EXCEL文件中
- 求助:在将文本文件插入表中时如何同时在每行最后一个字段插入一指定日期?
- 求zjcxc(邹建) 取表字段的SQL
- 表容量3G时候时连接超时的问题?
- ~~~~~关于SQL2000导回数据库的问题~~~~~
- amd三核cpu如何安装sql server 2000个人版
- 搜索了论坛,没有发现问此类查询的,急求答案
- sql存储过程,调用,没反回值`
- 关于bcp的问题(加急),大力,邹建请进
- 哪位高手能指导我一下这个排序问题?
- 到底该如何跨网段访问SQL Server,有一个明确的方案吗?只要能答出1000分也没问题
- 安装sql server2000总是提示挂起,十万火急
HOLDLOCK 将共享锁保留到事务完成,而不是在相应的表、行或数据页不再需要时就立即释放锁。HOLDLOCK 等同于 SERIALIZABLE。
NOLOCK 不要发出共享锁,并且不要提供排它锁。当此选项生效时,可能会读取未提交的事务或一组在读取中间回滚的页面。有可能发生脏读。仅应用于 SELECT 语句。
PAGLOCK 在通常使用单个表锁的地方采用页锁。
READCOMMITTED 用与运行在提交读隔离级别的事务相同的锁语义执行扫描。默认情况下,SQL Server 2000 在此隔离级别上操作。
READPAST 跳过锁定行。此选项导致事务跳过由其它事务锁定的行(这些行平常会显示在结果集内),而不是阻塞该事务,使其等待其它事务释放在这些行上的锁。READPAST 锁提示仅适用于运行在提交读隔离级别的事务,并且只在行级锁之后读取。仅适用于 SELECT 语句。
READUNCOMMITTED 等同于 NOLOCK。
REPEATABLEREAD 用与运行在可重复读隔离级别的事务相同的锁语义执行扫描。
ROWLOCK 使用行级锁,而不使用粒度更粗的页级锁和表级锁。
SERIALIZABLE 用与运行在可串行读隔离级别的事务相同的锁语义执行扫描。等同于 HOLDLOCK。
TABLOCK 使用表锁代替粒度更细的行级锁或页级锁。在语句结束前,SQL Server 一直持有该锁。但是,如果同时指定 HOLDLOCK,那么在事务结束之前,锁将被一直持有。
TABLOCKX 使用表的排它锁。该锁可以防止其它事务读取或更新表,并在语句或事务结束前一直持有。
UPDLOCK 读取表时使用更新锁,而不使用共享锁,并将锁一直保留到语句或事务的结束。UPDLOCK 的优点是允许您读取数据(不阻塞其它事务)并在以后更新数据,同时确保自从上次读取数据后数据没有被更改。
XLOCK 使用排它锁并一直保持到由语句处理的所有数据上的事务结束时。可以使用 PAGLOCK 或 TABLOCK 指定该锁,这种情况下排它锁适用于适当级别的粒度。
2. 要阻止另一个select , 则要手工加锁, select 默认是共享锁, select之间的共享锁是不冲突的, 所以, 如果只是共享锁, 即使锁没有释放, 另一个select一样可以下共享锁, 从而select出数据BEGIN TRAN
SELECT * FROM tb WITH(TABLOCKX)
UPDATE ....
COMMIT TRAN
-- 事务不提交或者回滚, 以保持锁不释放SELECT * FROM tb WITH(UPDLOCK, READPAST) -- UPDLOCK 让锁保留到事务结束, READPAST 跳过已经锁定的数据
=====================================================
select 产生的锁导致下一次select失败或者等待? 你是指并发中的另一个线程吧?
如:
real_name(*真名) ( ) 信誉:100 Blog
已经写了, 再加 READPAST 选项, 可以跳过已经锁的行, 这样, 无论你用几个线程, 那么SELECT都不会被阻塞, 它始终去读取未被锁定的行.
//这样做会产生应用瓶颈,好比让一条16车道的马路连接一座单车道的桥,马路再宽也要堵车的SELECT * FROM tb WITH(UPDLOCK, READPAST)
//这样的锁能对select产生影响吗?
如果是那样的话, 那就不存在问题了, 因为有UPDATE的SELECT, 你都使用UPDLOCK, 这样下的都是更新锁, 而更新锁与更新锁是有冲突的, 所以是有约束力的.
update Table_A set Y=1 where X=x请你明确告诉我:有没有可能有两次select到同一条记录?我认为这样加锁,实际上只是防止了两次update同一条记录
而并不会防止两次select同一条记录在select上加锁导致update失败从而间接导致整个过程失败,这并不是我需要的结果
因为这样仅仅保证了功能需求,而对性能需求是起反作用的
我必须增加额外的循环开销来处理如果失败
这样的话我还不如放弃并发,老老实实地等待update成功了再select
begin tran
update table set @X=x,flag=1 where flag=0 -- 取出同时设置已读
commit tran
select @X
update Table_A set Y=1 where X=x看你的两次怎么算, 如果第1次的已经提交事务了, 第2次的select才发出, 则第2次很有可能取得第1次的记录, 否则是不可能的.
取值的时候就锁表,然后接着更新.
update Table_A set Y=1 where X=x
我爱钻石
吼吼select X from Table_A where Y=0 for update//行锁,选中多少行纪录锁多少行纪录在遇到commit 或 rollback后解锁
update Table_A set Y=1 where X=x看你的两次怎么算, 如果第1次的已经提交事务了, 第2次的select才发出, 则第2次很有可能取得第1次的记录, 否则是不可能的.zjcxc(邹建):不明白你说的这句话呀!
如果第1次的已经提交事务了, 第2次的select才发出, 则第2次很有可能取得第1次的记录
他那个SELECT是有条件限制的就是说第一次事务结束之后Y就等于1了.按道理来说第二次是不应该取到重复的呀!
BEGIN TRAN
-- 事务不提交或者回滚, 以保持锁不释放SELECT * FROM tb WITH(UPDLOCK, READPAST)
-- UPDLOCK 让锁保留到事务结束, READPAST 跳过已经锁定的数据sp_locks @@spid
-- 查看被锁定的资源