能不能给个加锁的例子: 如表user(user_no int primary key,user_name varchar(20))的插入操作
如果就一句插入,加锁没有任何意义,sql会自动加锁
锁的示例设table1(A,B,C) A B C a1 b1 c1 a2 b2 c2 a3 b3 c31)排它锁 新建两个连接 在第一个连接中执行以下语句 begin tran update table1 set A='aa' where B='b2' waitfor delay '00:00:30' --等待30秒 commit tran 在第二个连接中执行以下语句 begin tran select * from table1 where B='b2' commit tran若同时执行上述两个语句,则select查询必须等待update执行完毕才能执行即要等待30秒2)共享锁 在第一个连接中执行以下语句 begin tran select * from table1 holdlock -holdlock人为加锁 where B='b2' waitfor delay '00:00:30' --等待30秒 commit tran在第二个连接中执行以下语句 begin tran select A,C from table1 where B='b2' update table1 set A='aa' where B='b2' commit tran若同时执行上述两个语句,则第二个连接中的select查询可以执行 而update必须等待第一个连接中的共享锁结束后才能执行 即要等待30秒3)死锁 增设table2(D,E) D E d1 e1 d2 e2 在第一个连接中执行以下语句 begin tran update table1 set A='aa' where B='b2' waitfor delay '00:00:30' update table2 set D='d5' where E='e1' commit tran
在第二个连接中执行以下语句 begin tran update table2 set D='d5' where E='e1' waitfor delay '00:00:10' update table1 set A='aa' where B='b2' commit tran同时执行,系统会检测出死锁,并中止进程 -------------------------------------------------------------- SET IMPLICIT_TRANSACTIONS ON --用户每次必须显式提交或回滚。否则当用户断开连接时, --事务及其所包含的所有数据更改将回滚SET IMPLICIT_TRANSACTIONS OFF --自动提交模式。在自动提交模式下,如果各个语句成功 --完成则提交。
看不太懂,原题是这样的:2个表,一个表(ID)用来存放当前雇员编号的最大值,一个表(Emp)用来存放雇员,每插入一个雇员,要先查询ID,得出新雇员的编号,并更新ID,在多用户的情况下,如何保证ID的正确性。 ID: IdNo int Emp: EmpNo int EmpName varchar(20)分不够可以再加。
declare @curid int begin tran insert into id(IdNo) select .... commit tran select @curid=@@IDENTITY update Emp set EmpNo=@curid .....
to chotanyng: ID表只有一条记录,就是当前雇员的最大编号,不是多条。还有,你这样写的话,如果插入完ID表一条刻记录,此时另一个用户也插入了,那么第一个用户再读取的编号可能就是第二个用户插入的编号了,这还是不同步。
如表user(user_no int primary key,user_name varchar(20))的插入操作
A B C
a1 b1 c1
a2 b2 c2
a3 b3 c31)排它锁
新建两个连接
在第一个连接中执行以下语句
begin tran
update table1
set A='aa'
where B='b2'
waitfor delay '00:00:30' --等待30秒
commit tran
在第二个连接中执行以下语句
begin tran
select * from table1
where B='b2'
commit tran若同时执行上述两个语句,则select查询必须等待update执行完毕才能执行即要等待30秒2)共享锁
在第一个连接中执行以下语句
begin tran
select * from table1 holdlock -holdlock人为加锁
where B='b2'
waitfor delay '00:00:30' --等待30秒
commit tran在第二个连接中执行以下语句
begin tran
select A,C from table1
where B='b2'
update table1
set A='aa'
where B='b2'
commit tran若同时执行上述两个语句,则第二个连接中的select查询可以执行
而update必须等待第一个连接中的共享锁结束后才能执行 即要等待30秒3)死锁
增设table2(D,E)
D E
d1 e1
d2 e2
在第一个连接中执行以下语句
begin tran
update table1
set A='aa'
where B='b2'
waitfor delay '00:00:30'
update table2
set D='d5'
where E='e1'
commit tran
在第二个连接中执行以下语句
begin tran
update table2
set D='d5'
where E='e1'
waitfor delay '00:00:10'
update table1
set A='aa'
where B='b2'
commit tran同时执行,系统会检测出死锁,并中止进程
--------------------------------------------------------------
SET IMPLICIT_TRANSACTIONS ON --用户每次必须显式提交或回滚。否则当用户断开连接时,
--事务及其所包含的所有数据更改将回滚SET IMPLICIT_TRANSACTIONS OFF --自动提交模式。在自动提交模式下,如果各个语句成功
--完成则提交。
ID:
IdNo int
Emp:
EmpNo int
EmpName varchar(20)分不够可以再加。
begin tran
insert into id(IdNo) select ....
commit tran
select @curid=@@IDENTITY
update Emp set EmpNo=@curid .....
ID表只有一条记录,就是当前雇员的最大编号,不是多条。还有,你这样写的话,如果插入完ID表一条刻记录,此时另一个用户也插入了,那么第一个用户再读取的编号可能就是第二个用户插入的编号了,这还是不同步。
只要保证对同一数据调用的时候读操作在写操作前面就可以了。read(1)
read(2)
write(1)
write(2)
将雇员资料传送到存储程序后,设定一个1000次的循环(具体多少次你自己设定,实际上这个循环几乎只执行一次),开始到(ID)表中查询最大ID号加1后得到即将要存入的ID号,然后不是马上存储,而是将刚得到的ID号和Emp表中的ID进行比对,判断是否重复,如果重复说明在短时间内有别的用户存储了数据,那将又开是重复到(ID)表中查询新的ID号,直到存储完毕!为了确保雇员数据存储成功,存储完毕后进行一次数据校验,返回存储结果,就会万无一失了!
这里只是提供思路给你,具体怎么做你肯定清楚!希望你能尽快解决这个问题!