Transactions in Sybase

if exists (select 1
            from  sysobjects
            where  id = object_id('tA2')
            and    type = 'U')
   drop table tA2
go


begin transaction tA2
LOCK TABLE tA2 IN SHARE MODE
commit transaction tA2

if exists (select 1
            from  sysobjects
            where  id = object_id('tB1')
            and    type = 'U')
   drop table tB1
go

/*==============================================================*/
/* Table: tA                                                                                                             */
/*==============================================================*/
create table tA2 (
     name                char(20)                        null,
     price                 int                            default 0 null,
   )
go
/*==============================================================*/
/* Table: tB                                                                                                            */
/*==============================================================*/
create table tB2 (
     name                    char(20)                        null,
     saleprice               int                            default 0 null,
   )
go
ALTER TABLE tA1 LOCK DATAROWS
ALTER TABLE tB1 LOCK DATAROWS
go
insert into tA2(name, price) values ('book',20)
insert into tA1(name, price) values ('book1',20)
insert into tB1(name, saleprice) values ('book',10)
insert into tB1(name, saleprice) values ('book1',10)


select * from tA2
select * from tB1

begin tran
insert into tA1(name, price) values ('book2',20)
waitfor delay '00:00:05'
insert into tB1(name, saleprice) values ('book2',10)
commit tran


begin tran
update tB set saleprice=saleprice+10000 where name='book'
update tA set price=price+20000 where name='book'
commit tran

 

-- test

begin tran
update tA2 set price=price+100 where name='book'
waitfor delay '00:00:05'
update tB2 set saleprice=saleprice+100 where name='book45'
commit tran

 

begin tran
insert into tB1(name, saleprice) values ('book3',10)
waitfor delay '00:00:05'
insert into tA1(name, price) values ('book3',20)

commit tran


drop procedure P1
select * from tA2


insert into tA2(name, price) values ('book44',20)


drop procedure P1

select * from tA2
select * from tB2

exec P1

create procedure P1
as
begin

begin transaction V1
insert into tA2(name, price) values ('book45',20)
exec P2  
rollback transaction V1
end


drop procedure P2
create procedure P2
as
begin
begin transaction V2
insert into tB2(name, saleprice) values ('book45',20)   
commit transaction V2
end


 

由于在使用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
测试说明,事 务并发,并相互有竞争,但没有死锁时,两个都成功。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值