sql中事务只针对一个update,delete,insert语句,如果一段程序中有超过一个这样的语句,就需要每个都判断是否出错,否则就会出现若干我们不希望的情形出现,举例如下(表结构见最后):
1,有三个
insert语句(or其它语句),第一个出错,第二个对了,第三个错了,如下:
BEGIN
BEGIN TRANSACTION
print 'bb'
insert into testNewID (a) values('aa')
IF @@error <> 0
BEGIN
print '1'
ROLLBACK TRANSACTION
return
END
-- select * from dd
insert into testNewID(id,a) values(2,'bb')
IF @@error <> 0
BEGIN
print '2'
ROLLBACK TRANSACTION
return
END
insert into testnewid(a) values('cc')
IF @@error <> 0
BEGIN
print '3'
ROLLBACK TRANSACTION
return
END
BEGIN
print 'finished'
COMMIT TRANSACTION
END
SET NOCOUNT OFF
END
--
--delete from testnewid
--select * from testNewID
这样写就没问题,因为每个insert语句都经过了判断,一旦出错,回滚整个事务。如果这样写:
2,
BEGIN
BEGIN TRANSACTION
print 'bb'
insert into testNewID (a) values('aa')
insert into testNewID(id,a) values(2,'bb')
insert into testnewid(a) values('cc')
IF @@error <> 0
BEGIN
print '3'
ROLLBACK TRANSACTION
return
END
BEGIN
print 'finished'
COMMIT TRANSACTION
END
SET NOCOUNT OFF
END
--
--delete from testnewid
--select * from testNewID
这样的话@@error只收到最后一个insert语句的信息,它是对的,所以@@error的值是0,没错,所以不回滚,commit语句执行,第一个插入成功,第二个失败,第三个成功,没有起到事务的作用。
另外,如果程序中除了insert,update,delete之外的语句出现错误,那么整个程序停止,和事务没有关系。事务只针对insert,update,delete这三种操作。
附:用到的表结构 testnewid(id,a),id自增
以上是我自己的一点小经验,可能有不对和不完善的地方,哪位看到了请千万指出来,万分感谢。
今天得到tony的指点,原来这个事务可以优化一下,变得简单:
Begin TRANSACTION
DECLARE @Err int
SET @Err = 0
--在每一个操作语句之后(包括select等除update,insert,delete之外的语句)判断一下@@error
IF @@error <> 0
Set @Err = @@Error
--如果以上的操作中有一个有问题,那么@Err肯定不是零了。就 rollback,如果是零说明没有出错的,
--就commit
IF @Err <> 0
BEGIN
ROLLBACK TRANSACTION
END
ELSE
BEGIN
COMMIT TRANSACTION
END