由于在使用sybase的时候很多东西没有明白,自己写了几个测试用例来分析实际的处理方式,如果哪位有相关的资料或更好的方法,谢谢共享一下。
测试总结:
1、在事务中,要更新的表不是事务开始时就全部锁定了,只是在用到时才锁定,等提交时才释放。这就要注意一个问题,在事务中,前面查询的数据,在后面该值可能已经改变了。
2、事务并发,并相互有竞争,但没有死锁时,两个都成功。
3、事务并发,并相互有竞争,有死锁时,只有一个成功,最后发现死锁的事务才可成功。
测试环境:
数据库版本:sybase_win_12.5.2
sql执行程序:sqladv
1、先建2个测试表tA,tB;插入测试数据
if exists (select 1
from sysobjects
where id = object_id('tA')
and type = 'U')
drop table tA
go
if exists (select 1
from sysobjects
where id = object_id('tB')
and type = 'U')
drop table tB
go
/*==============================================================*/
/* Table: tA */
/*==============================================================*/
create table tA (
name char(20) null,
price int default 0 null,
)
go
/*==============================================================*/
/* Table: tB */
/*==============================================================*/
create table tB (
name char(20) null,
saleprice int default 0 null,
)
go
ALTER TABLE tA LOCK DATAROWS
ALTER TABLE tB LOCK DATAROWS
go
insert into tA(name, price) values ('book',20)
insert into tB(name, saleprice) values ('book',10)
go
查询结果result:
select * from tA
select * from tB
name price
---- -----------
book 20
name saleprice
---- -----------
book 10
测试用例1:
事务和别的sql发生并发的情况1:
测试代码:
事务代码tran1:
begin tran
update tA set price=price+100 where name='book'
waitfor delay '00:00:05'
update tB set saleprice=saleprice+100 where name='book'
commit tran
并发代码code1:
update tA set price=price+20000 where name='book'
测试步骤:
执行tran1,然后马上执行并发代码code1
测试结果:
tran1执行完成后code1也执行完成了。
tran1:
(1 row affected)
(1 row affected)
code1:
(1 row affected)
result:
name price
---- -----------
book 20120
name saleprice
---- -----------
book 110
测试说明,在事务处理成功后,并发才能执行。
测试用例2:
事务和别的sql发生并发的情况2:
测试代码:
事务代码tran1:
begin tran
update tA set price=price+100 where name='book'
waitfor delay '00:00:05'
update tB set saleprice=saleprice+100 where name='book'
commit tran
并发代码code2:
update tB set saleprice=saleprice+10000 where name='book'
测试步骤:
执行tran1,然后马上执行并发代码code2
测试结果:
code2马上能成功,tran1也能按时执行成功。
tran1:
(1 row affected)
(1 row affected)
code2:
(1 row affected)
result:
name price
---- -----------
book 120
name saleprice
---- -----------
book 10110
测试说明,并发代码在事务没有锁定相关记录时,还是可以修改的。
用例1和用例2说明,在事务中,要更新的表不是事务开始时就全部锁定了,只是在用到时才锁定,等提交时才释放。
这就要注意一个问题,在事务中,前面查询的数据,在后面该值可能已经改变了。
测试用例3:
事务和事务发生并发的情况1:
测试代码:
事务代码tran1:
begin tran
update tA set price=price+100 where name='book'
waitfor delay '00:00:05'
update tB set saleprice=saleprice+100 where name='book'
commit tran
事务代码tran2:
begin tran
update tB set saleprice=saleprice+10000 where name='book'
update tA set price=price+20000 where name='book'
commit tran
测试步骤:
执行tran1,然后马上执行tran2
测试结果:
tran1执行完成后tran2也执行完成了,但tran2出错了。
tran1:
(1 row affected)
(1 row affected)
tran2:
(1 row affected)
Server Message: Number 1205, Severity 13
Server 'ONLINEDB', Line 5:
Your server command (family id #0, process id #17) encountered a deadlock situation. Please re-run your command.
result:
name price
---- -----------
book 120
name saleprice
---- -----------
book 110
测试说明,事务并发,并相互有竞争,但没有死锁时,两个都成功。
测试用例4:
事务和事务发生并发的情况1:
测试代码:
事务代码tran1:
begin tran
update tA set price=price+100 where name='book'
waitfor delay '00:00:05'
update tB set saleprice=saleprice+100 where name='book'
commit tran
事务代码tran3:
begin tran
update tA set price=price+20000 where name='book'
update tB set saleprice=saleprice+10000 where name='book'
commit tran
测试步骤:
执行tran1,然后马上执行tran3
测试结果:
tran1执行完成后tran3也执行完成了。
tran1:
(1 row affected)
(1 row affected)
tran3:
(1 row affected)
(1 row affected)
result:
name price
---- -----------
book 20120
name saleprice
---- -----------
book 10110
测试说明,事务并发,并相互有竞争,但没有死锁时,两个都成功。
测试用例5:
事务和事务发生并发的情况2:
测试代码:
事务代码tran1:
begin tran
update tA set price=price+100 where name='book'
waitfor delay '00:00:05'
update tB set saleprice=saleprice+100 where name='book'
commit tran
事务代码tran4:
begin tran
update tB set saleprice=saleprice+10000 where name='book'
update tA set price=price+20000 where name='book'
commit tran
测试步骤:
执行tran1,然后马上执行tran4
测试结果:
tran1执行完成后tran4也执行完成了,但tran1完成时间是12秒。
tran1:
(1 row affected)
(1 row affected)
tran4:
(1 row affected)
Server Message: Number 1205, Severity 13
Server 'ONLINEDB', Line 3:
Your server command (family id #0, process id #17) encountered a deadlock situation. Please re-run your command.
result:
name price
---- -----------
book 120
name saleprice
---- -----------
book 110
测试说明,事务并发,并相互有竞争,有死锁时,只有一个成功,最后发现死锁的事务才可成功。
测试用例6:
事务和事务发生并发的情况3:
测试代码:
事务代码tran1:
begin tran
update tA set price=price+100 where name='book'
waitfor delay '00:00:05'
update tB set saleprice=saleprice+100 where name='book'
commit tran
事务代码tran5:
begin tran
update tB set saleprice=saleprice+10000 where name='book'
waitfor delay '00:00:10'
update tA set price=price+20000 where name='book'
commit tran
测试步骤:
执行tran1,然后马上执行tran5
测试结果:
tran1执行完成后tran5也执行完成了,但tran1完成时间是12秒。
tran1:
(1 row affected)
Server Message: Number 1205, Severity 13
Server 'ONLINEDB', Line 5:
Your server command (family id #0, process id #15) encountered a deadlock situation. Please re-run your command.
tran5:
(1 row affected)
(1 row affected)
result:
name price
---- -----------
book 20020
name saleprice
---- -----------
book 10010
测试说明,事务并发,并相互有竞争,有死锁时,只有一个成功,最后发现死锁的事务才可成功。
测试用例7:
事务和事务发生并发的情况4:
测试代码:
事务代码tran1:
begin tran
update tA set price=price+100 where name='book'
waitfor delay '00:00:05'
update tB set saleprice=saleprice+100 where name='book'
commit tran
事务代码tran6:
begin tran
update tA set price=price+20000 where name='book'
waitfor delay '00:00:10'
update tB set saleprice=saleprice+10000 where name='book'
commit tran
测试步骤:
执行tran1,然后马上执行tran6
测试结果:
tran1执行5秒后完成,tran6执行15秒才完成。
tran1:
(1 row affected)
(1 row affected)
tran5:
(1 row affected)
(1 row affected)
result:
name price
---- -----------
book 20120
name saleprice
---- -----------
book 10110
测试说明,事务并发,并相互有竞争,但没有死锁时,两个都成功。