原问题:
SQL Server 2000是表锁?
创建一个测试表TestTrans:
———————————-
CREATE TABLE [dbo].[TestTrans] (
[testid] [int] NOT NULL ,
[contactname] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[contactage] [int] NULL
) ON [PRIMARY]
GO
———————————————
打开查询分析器, 在一个窗口中运行如下语句:
———————————————–
begin transaction
insert into TestTrans
(testid, contactname, contactage) values (9, 'contact46', '32')
———————————————–
在查询分析器再打开一个窗口中运行如下语句
————————————-
select count(*) from TestTrans
————————————-
结果, 第二个窗口的查询一直在等待, 没有返回结果.
在MySQL 5.0(InnoDB)重复以上测试, 第二个窗口不会等待立即返回结果.
SQL Server默认是READ COMMITTED隔离等级, MySQL默认是REPEATABLE READ隔离等级.
网友回:
我做了个试验,给你参考下:
试验环境 SQL SERVER 2005 EXPRESS
准备工作:
CREATE TABLE [dbo].[TestTrans] (
[testid] [int] NOT NULL ,
[contactname] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[contactage] [int] NULL
) ON [PRIMARY]
insert into TestTrans
(testid, contactname, contactage) values (9, 'contact46', '32')
insert into TestTrans
(testid, contactname, contactage) values (10, 'contact46', '34')
试验第1步:
begin transaction
select contactage
from testtrans
where testid=9
第2步:新查询窗口
update testtrans
set contactage='45'
where testid=10 执行OK!
第3步:新查询窗口
select *
from testtrans
结果是 9 contact46 32
10 contact46 45 执行OK!
网友又回:
试验2
第1步:BEGIN TRANSACTION
update testtrans
set contactage='41'
where testid=9
第2步:select *
from testtrans
WHERE TESTID=10 一直等待,无返回结果!
第3步:
update testtrans
set contactage='50'
where testid=10 一直等待,无返回结果!
本人回:1、SQL SERVER的锁机制是这样的:
当对表进行修改时,系统首先会在TABLE和PAGE上加一个IU或IX锁,也就是意向锁,然后给被操作行加一个U锁或X锁,因为对表中行修改的事务没结束,这些锁是一直存在的,当你查询该表时,要加S锁,因为S锁和已经加的IU或IX模式不兼容,因此,查询只能等待。
2、而MYSQL中的INNODB引擎在并发访问方面的特点有点类似ORACLE(MVC),在这种并发的修改和查询间不会发生等待,所以两种操作不会冲突,不会产生等待,这里我不确信的是:MYSQL中INNODB的默认事务隔离级别确实是REPEATABLE READ吗?oracle中和mssql的都是RC的,而DB2是另外一种。
3、在sqxycl的第一个试验中,第一步因为只有一个查询,虽然从概念上讲,它可以是一个事务,可在实际中,它也许并不会启动一个事务或维持表上锁的存在,你可以跟踪一下;而在第二步中,你虽然对表进行了修改,但MSSQL中,默认每条DML都算是一个事务,完成后就提交,因此它所维持的锁随即释放掉,因此在第三步的查询中,不会产生阻塞或等待;
而SYXYCL得最后一个试验中,理论符合该贴第一条,就是在第一步中启动了一个事务,该事务中,维持了TABLE和PAGE级的IU锁,因为该事务没提交,所以该意向锁一直维持而不释放,所以阻塞了后两步中模式和IU不兼容的操作,产生了等待。
本人又回:再补充两点:
1、MYSQL中innodb缺省隔离级别确实是REPEATABLE READ;
2、通过以下代码:
use test1
go
begin tran test_trans
select * from tab1
go
确实能启动一个事务,而且在事务也会产生一些锁,有数据库级、对象级、行级或键级等,但多数是共享锁或意向锁,当然其间也会产生一些IX锁,但最终都会释放掉,该R事务不会与其他W事务产生RR阻塞和RW阻塞。
[ 本帖最后由 sqysl 于 2009-6-5 06:43 编辑 ]
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/8484829/viewspace-605576/,如需转载,请注明出处,否则将追究法律责任。
主题测试文章,只做测试使用。发布者:深沉的少年,转转请注明出处:http://www.cxybcw.com/184781.html