学习BEGIN TRAN ||COMMIT TRAN

来源:互联网 发布:农村淘宝合伙人这么难 编辑:程序博客网 时间:2024/06/05 17:35

今天在项目中用到了一个存储过程需要同时项三个表更新数据,如果其中一个有错,则将导致数据库数据不同步,为解决这一问题,查到了有BEGIN TRAN ||COMMIT TRAN方法可以解决~

 

在网上搜了一会,看到一个帖子很受益:内容如下:

 

帖子地址:http://topic.csdn.net/t/20031030/15/2410812.html

 

 

 

楼主问题:

我在使用   SqlServer   的时候遇到这样一个问题.  
   
  我打算用下面的语句:  
   
  begin   tran;  
   
  insert   into   TabA   values(1);  
   
  insert   into   TabB   values(1);  
   
  commit   tran;  
   
  想的是两个插入操作要么同时成功,   要么   rollback.  
   
  但我发现它的执行结构却是:  
   
  ------------------------------------------------------------------------------------  
  服务器:   消息   2627,级别   14,状态   1,行   1  
  违反了   PRIMARY   KEY   约束   'PK_tabA'。不能在对象   'TabA'   中插入重复键。  
  语句已终止。  
   
  (所影响的行数为   1   行)  
  ------------------------------------------------------------------------------------  
   
  第一条语句因为主键约束,   插入失败.  
   
  而第二条语句成功了.   faint.  
  如果这样的话,   那   begin   tran/commit   tran   语句还有什么用?  
   
  大侠们给指点指点吧.   谢谢啦.

 

**************************************************

 

大家的回答

1 楼txlicenhe(马可)回复于 2003-10-30 15:46:41 得分 5

begin   tran;  
   
  insert   into   TabA   values(1);  
   
  if   @@error   <>   0     rollback  
  insert   into   TabB   values(1);  
  if   @@error   <>   0     rollback  
   
   
  commit   tran;  
  Top

2 楼pengdali()回复于 2003-10-30 16:06:40 得分 15

SET   XACT_ABORT   on   ----设置  
  go  
   
  create   table   #Table1   (a   tinyint)  
  go  
  begin   tran  
      insert   #table1   values(1)                             ----成功  
      insert   #table1   values(1000)                       ----这句将报错  
  commit   tran  
  go  
  select   *   from   #table1    
  go  
  drop   table   #table1Top

3 楼LoveSQL(努力奋斗ing)回复于 2003-10-30 16:26:52 得分 5

前面加上这句话就好了  
  SET   XACT_ABORT   on   ----设置  
  或是  
  在程序里判断有错误时执行rollback   tran   这个语句也可以。  
  Top

4 楼longleaver(易水寒)回复于 2003-10-31 01:24:05 得分 5

begin   trans  
      insert   into   tableA   values(1)  
      if   @@error>0   or   @@rowcount<>1    
            goto   NeedRollBack  
         
      insert   into   tableB   values(2)  
       
      NeedRollBack:  
      if   @@error>0   or   @@rowcount<>1  
              rollback   tran  
      esle  
              commit   tranTop

5 楼iloveyoustt(娃娃)回复于 2003-10-31 08:33:55 得分 0

你没有用到rollback   tranTop

6 楼zjcxc(邹建)回复于 2003-10-31 08:59:19 得分 0

要判断错误,如果出错,就回滚.Top

7 楼zjcxc(邹建)回复于 2003-10-31 09:09:32 得分 5

--如果要用判断错误的方法处理,应该这样做:  
   
  --测试的表  
  create   table   tb(  
  id   int     not   null     constraint   PK_sys_zj_fielddict   primary   key  
          ,aa   int)  
   
  --事务处理  
  begin   tran  
  insert   into   tb   values(1,1)  
  if   @@error<>0   goto   lb_rollback  
  insert   into   tb   values(1,1)  
  if   @@error<>0   goto   lb_rollback  
  insert   into   tb   values(2,1)  
  if   @@error<>0   goto   lb_rollback  
  insert   into   tb   values(2,1)  
  if   @@error<>0   goto   lb_rollback  
  insert   into   tb   values(3,1)  
  if   @@error<>0   goto   lb_rollback  
  lb_commit:  
  commit   tran  
  goto   lb_ok  
  lb_rollback:  
  rollback   tran  
   
  --显示结果  
  lb_ok:  
  select   *   from   tb  
  drop   table   tbTop

8 楼zjcxc(邹建)回复于 2003-10-31 09:16:55 得分 15

txlicenhe(马可)   和   longleaver(易水寒)   的方法是不能处理的,两位可以自行测试一下  
   
  而设置:  
  SET   XACT_ABORT   on  
  的方法可以做到回滚整个事务,达到楼主的要求,但要注意一点:  
   
  --创建测试表  
  create   table   tb(  
  id   int     not   null     constraint   PK_sys_zj_fielddict   primary   key  
          ,aa   int)  
   
  --设置选项  
  SET   XACT_ABORT   on  
   
  --事务处理  
  begin   tran  
  insert   into   tb   values(1,1)  
  insert   into   tb   values(1,1)  
  insert   into   tb   values(2,1)  
  commit   tran  
   
  --显示结果  
  /*--------注意  
          如果这样写的话,后面的语句不会被执行,如果要执行后面的语句,要在这句后面加上GO,仅查询分析分析器支持,所以如果是在存储过程中,要保证commit   tran后面没有其他语句,否则出错时,其他语句不会被执行  
  -----------*/  
  select   *   from   tb  
  drop   table   tb  

 

 

*******************************************************

 

通过邹健的回答,得到的了我想要的答案,并明白了使用方法

 

哎,大侠就是大侠,人家一说我就明白了

 

看微软的帮助文档又是一顿胡诌,看的我是一头雾水的~

 

特此记录,以备后用

 

原创粉丝点击