1、select语句也能加锁共享锁
共享 (S) 锁允许并发事务读取 (SELECT) 一个资源。资源上存在共享 (S) 锁时,任何其它事务都不能修改数据。2、死锁问题往往和效率相关,提高查询、修改效率是一举两得的事情
共享 (S) 锁允许并发事务读取 (SELECT) 一个资源。资源上存在共享 (S) 锁时,任何其它事务都不能修改数据。2、死锁问题往往和效率相关,提高查询、修改效率是一举两得的事情
解决方案 »
- 这条sql语句写的对吗?执行起来似乎进入死循环一样
- 如何合并两个结构不完全相同的记录集?
- windows的服务都有一个启动账户,这个启动账户有什么意义?sql server的启动账户又有什么意义?
- 求一个sql语句(sqlserver用) 关于创建数据库 以及表
- 求一SQL语句
- 在 SQL Profiler , 執行一個追蹤 , 很容易出現錯誤提示: 無法讀取追蹤資料.請問這是什么原因?
- dbf 急呀 在线等待 谢谢了
- 求一sql语句写法,统计方面的
- 更改2000管理员密码后,sqlserver无法登陆?
- 在同一张表里能怎么约束两个字段不能同时为空
- SQLServer2005远程连接出问题
- 今天高兴,来送分了!
--with 可以省略
不能。至少SQL Server 2000不支持这种写法。
问题是我现在作为牺牲品的只是一个查询而已,根本不存在更新,不需要获得任何资源的锁啊!!!问什么SQL Server 会认为我这个查询需要锁定某个资源而牺牲这个查询呢???我现在需要的是不管这个表有没有锁定我都可以查询,我不需要更新,只要能够查询就可以了!如果我在查询中加上(nolock) 那是不是说尽管别人锁定了该表我都可以查询还是说我在查询这个表的时候不加锁呢???在什么情况下会造成一个查询会对表加上共享锁呢???
DBCC TRACEON(1204, -1)DBCC TRACEON(1205, -1)DBCC TRACEON(3605, -1)把错误提示再发出来。可以找出死锁对象。解决方案:
可以尝试在select时加上X锁,防止其他进程同时锁定。如:select * from table1 with(ROWLOCK,XLOCK)
我上面的信息就是通过DBCC TRACEON(1204, -1)在日志中得到的
你的DBCC TRACEON(1205, -1),DBCC TRACEON(3605, -1)跟踪什么的呢?好像没有这两个跟踪标志吧.按照帮助中讲产生死锁的原因是因为两个事务交叉申请彼此锁定的资源造成的.但我现在是一个执行查询语句的事务怎么可能和另外一个事务产生交叉锁定呢?按理只会造成阻塞啊!我上面的跟踪已经是几个死锁信息的了.有什么办法使到查询语句不锁定表(使用With (nolock)吗?).
解决方案:
可以尝试在select时加上X锁,防止其他进程同时锁定。如:select * from table1 with(ROWLOCK,XLOCK)-----------------------------------------------
很难明白你的方案会有效,如果加S锁都死锁了,加X锁怎么可能解决问题呢?会不会变成频频出错?
我感觉楼主的系统一定有性能问题,select返回的数据太多太慢会造成S锁长期不释放,更新操作只能等待;更新操作太慢造成X锁不释放,其他操作只能等待。
所以有以上的回复,希望楼主能正视效率问题。
你的DBCC TRACEON(1205, -1),DBCC TRACEON(3605, -1)跟踪什么的呢?好像没有这两个跟踪标志吧.按照帮助中讲产生死锁的原因是因为两个事务交叉申请彼此锁定的资源造成的.但我现在是一个执行查询语句的事务怎么可能和另外一个事务产生交叉锁定呢?按理只会造成阻塞啊!我上面的跟踪已经是几个死锁信息的了.有什么办法使到查询语句不锁定表(使用With (nolock)吗?).
-------------------------------------
一般检测死锁的方法是:使用traceon跟踪和profiler同时定位死锁信息。你上面的信息确实是1204打出来的,但是还有些信息上面是无法提供的。如果你看了sql2k的帮助文档你会发现sql server建议使用1204和3605来确定死锁。所以多些信息对死锁的监测时有好处的!还有帮助文档中说的两个互相等待的事务你没有发现。那是因为你不知道有其他的因素会和你的使用导致死锁,所以你才要找呀!而且两个事务互相等待对方的资源说明的是死锁的原理,但是这个原理会有很多表现的现象,甚至有的时候你会发现数据库自身的字典表和内部线程资源发生了死锁。使用With (nolock)还是With (ROWLOCK,XLOCK)要根据你的业务需求,如果是否update要由select的结果来决定的话,你只能用后者。如果没有直接联系,前者也是可以的。这要根据你对死锁原因排查后,再作决定。
很难明白你的方案会有效,如果加S锁都死锁了,加X锁怎么可能解决问题呢?会不会变成频频出错?
我感觉楼主的系统一定有性能问题,select返回的数据太多太慢会造成S锁长期不释放,更新操作只能等待;更新操作太慢造成X锁不释放,其他操作只能等待。
所以有以上的回复,希望楼主能正视效率问题。
--------------------------------------------------
首先要理解S锁和X锁的区别。S锁是指多个数据库连接可以在同一时间共同加持在相同的资源上。而X锁是排他的,在同一时间只能有一个数据库连接取得资源的使用权。而楼主的死锁原因就是因为高并发情况下,有多个数据库连接同时对同一资源加了S锁,而其中某一个数据库连接update的时候,要升级S锁为X锁。但是它只有等待其他数据库连接释放S锁,他才能升级为X锁,所以他在等。但是在他等待别人释放S锁的时候,那个连接却也要进行update,也要升级为X锁,因此造成了互相等待对方释放资源的局面,因此导致了死锁!
如果在select的时候加上With (ROWLOCK,XLOCK),其实就是首先杜绝大家同时施加S锁的可能,即对这个资源大家要串行访问,虽然效率低,但是最大限度避免死锁。最典型的例子应该是自己写的生成主键存储过程的时候,这种现象最容易发生。
select 时候产生死锁的原因.往往是别外一个用户进行批理对表进行增删改的时候才会发生.
他的解释应该说明了楼主的死锁主要产生过程从解决问题方面来说,设法提高效率(或者说性能优化,不过性能优化的范围大了些)是成本最低的好像楼主一直没说硬件情况
但不知道这样做的后遗症大不大.如果改为with(ulock)又怕降低并发量.按照现在的死锁频率
基本可以满足我的要求了.真的很感谢大家的提示与意见啊!!!
一般检测死锁的方法是:使用traceon跟踪和profiler同时定位死锁信息。你上面的信息确实是1204打出来的,但是还有些信息上面是无法提供的。如果你看了sql2k的帮助文档你会发现sql server建议使用1204和3605来确定死锁。所以多些信息对死锁的监测时有好处的!
-------------------------------
3605是用来将信息发送到log中的,而使用1205可以得到更多的信息。
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED