ALTER PROCEDURE [dbo].[UpdateReadTest]
AS
BEGIN
BEGIN TRANSACTION
declare @num int
select @num = Num from ReadTest rowlock where Id = 1
set @num = @num + 1
update ReadTest set Num = @num where Id = 1
--update ReadTest set Num = Num + 1 where Id = 1
COMMIT
END今天在做多线程并发测试的时候,发现在事务里给查询数据加 rowlock 无效,谁能解答一下?
在4x1000以下看不出错误,但并发线程达到5以后开始出现数据错误。
解决方案 »
- 牛人请进
- isnull具体怎么用?
- grid表里显示小数有很多位,我只要显示两位,请问怎么设置
- ~~~~怎样产生365与730之间随意的一个数字?
- sql2000中把另一个相同数据库中的相同表多出来的记录复制到本表中 求助
- 如果有一个字段,里面是10个数字,现在要选出所有符合给出的10个数字中的任意的9个数字的所有记录。这个SQL应该怎么写?
- 简单的数据库语句,在线等!多谢
- 数据库PK代表主关键字,FK代表什么,其中'F'代表什么英语单词?
- 请问VFP能访问sql server7.0里的数据库吗?若能,该如何建立连接?
- 查询数据库,查询某个ID,注册时间大于30天或是一个月,并且一个月内有几个下级
- 求工具软件
- 关于一条记录的问题
from ReadTest with(holdlock,tablockx)
seriallzable
select @num = Num from ReadTest with(rowlock) where Id = 1
static void changeNumTran(object id)
{
thradNum++;
for (int i = 0; i < 10000; i++)
{
int num;
SqlParameter param = new SqlParameter("@id", id);
DbHelperSQL.RunProcedure("UpdateReadTest2", new[] { param }, out num);
}
thradNum--;
} // 将原始数据清零
DbHelperSQL.ExecuteSql("update ReadTest set Num = 0");
DateTime begin = DateTime.Now;
for (int j = 1; j <= 20; j++ )
for (int i = 0; i < 5; i++)
{
var thread = new Thread(ChangeNum);
//var thread = new Thread(changeNumTran);
thread.Start(j);
} Thread.Sleep(100);
while (thradNum > 1)
Thread.Sleep(100);我用c#做的开发,按照上面的做法,加xlock后的确能保证数据的准确性。
不过实测发现,好像这个时候不是行级锁,而变成表锁了。
上面的代码
for (int j = 1; j <= 20; j++ )
标示同时对20行做并发修改,如果是行级锁,没增加一个行并发,会将提高数据库的每秒的执行数,但从实际测试来看,并发操作5行数据和并发操作20行数据每秒执行的sql数是固定的。这个是修改后的存储过程ALTER PROCEDURE [dbo].[UpdateReadTest2]
@id int
AS
BEGIN
BEGIN TRANSACTION
declare @num int
select @num = Num from ReadTest where Id = @id
set @num = @num + 1
update ReadTest set Num = @num where Id = @id
waitfor DELAY '000:00:00.01' -- 延时,不让并发时不让数据库的io和cpu成为瓶颈
--update ReadTest set Num = Num + 1 where Id = 1
COMMIT
END