数据库的问题,事务定义中,COMMIT语句和ROLLBACK语句的作用是啥?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据库的问题,事务定义中,COMMIT语句和ROLLBACK语句的作用是啥?相关的知识,希望对你有一定的参考价值。

事务定义中,COMMIT语句和ROLLBACK语句的作用是什么?

Commit表示提交。Rollback的意思是回滚。

甲骨文公司(是一家全球数据库软件公司,总部位于美国加州红杉城。2008年,按收入计算,甲骨文公司是全球第三大软件公司,仅次于微软和IBM。

Oracle数据库产品被财富榜上的前1000家公司使用,也被许多大型网站使用。甲骨文公司于1989年进入中国,在北京、上海、广州和成都设有分支机构。

扩展资料:

数据库技术的应用及特点

数据库最初是用作大型公司或组织中大规模事务处理的基础。后来,随着个人电脑的普及,将数据库技术移植到pc中,实现单用户个人数据库应用。然后由于PC机在工作组内联网,数据库技术被移植到工作组级。

数据库现在在Internet和Intranet上广泛使用。在20世纪60年代中期,数据库技术被用来解决文件处理系统的问题。当时,数据库处理技术仍然非常脆弱,经常出现应用程序无法提交的情况。

20世纪70年代,关系模型的诞生为数据库专家提供了一种构建和处理数据库的标准方法,促进了关系数据库的发展和应用。

现在,数据库技术与Internet技术一起被用来在组织内联网、部门局域网、甚至WWW上发布数据库数据。

参考技术A 好比饭店和送菜的菜农之间的关系。饭店是数据库。commit语句是菜农成功将菜送到了饭店,饭店查验蔬菜合格并收下了。rollback语句是饭店发现菜有问题,拒收并将菜全部退给菜农。 参考技术B COMMIT语句 是将所做的有关数据库的操作提交给数据库
ROLLBACK语句 是用于放弃自上一个COMMIT、ROLLBACK或CONNECT操作后的所有数据库操作
参考技术C COMMIT 是提交
ROLLBACK 是回滚
2者都会释放undo空间
参考技术D COMMIT是表示【提交】,就是提交事务的所有操作。
具体地说,就是将事务中的所有对数据库的更新写回到磁盘上的物理数据库中去,事务正常结束。
ROLLBACK指的是【回滚】,即是在事务的运行过程中,发生了某种故障,事务不能继续执行,系统将事务中对数据库的所有的已完成的操作全部撤销,回滚到事务开始之前的状态。
总之,就是一个成功,一个不成功
希望对你有帮助

SqlServer中嵌套事务使用--事务计数指示 BEGIN 和 COMMIT 语句的数目不匹配 --根本问题

转自  :SqlServer中嵌套事务使用--事务计数指示 BEGIN 和 COMMIT 语句的数目不匹配 --根本问题

问题:

1. System.Data.SqlClient.SqlException (0x80131904): EXECUTE 后的事务计数指示 BEGIN 和 COMMIT 语句的数目不匹配。上一计数 = 1,当前计数 = 0。

2. EXECUTE 后的事务计数指示 BEGIN 和 COMMIT 语句的数目不匹配。上一计数 = 0,当前计数 = 1。

后面的内容,是我之前写的东西,主要是一些测试代码,但是呢,我没有很深入的理解。现在直接说清楚本质的东西,把后面的精华再提上来说。 

  • 提交的事务不能撤销或回滚。
  • 当不存在打开的事务时,@@trancount 等于 0。
  • 执行 begin tran [tranName]语句将 @@trancount 增加 1。
  • 执行commit tran [tranName]语句将 @@trancount 减小 1。
  • 执行 rollback tran  会回滚整个事务并设置@@trancount 为 0。
  • 执行 " rollback tran  tranName"语句时有两种情况:

if(tranName 之前 是用 " Save Tran tranName" 建立的 )  @@trancount值不变

否则,@trancount 减小1              

      注意:save tran 命令,不会使@@trancount加1

分析:

只要提交或者回滚事务后,程序内部改变了事务参数@@TRANCOUNT,就会出上述的错误,无一例外。

试图直接用Sql "  set @@trancount = 1;",这是sqlserver 不允许做的。

各位,出现上面的错误,最多的可能是在嵌套事务中。

 

如果不嵌套:没有begin tran前,@@trancount为0;  begin tran后,@@trancount  此时为1;完事后就commit或rollback,@@trancount  此时为0;--不般我们是写不错的。

嵌套呢

    看看我之前写的一个存储过程:

              

[sql] view plaincopy
 
  1. declare @trancount int --commit,rollback只控制本存储过程   
  2.     set @trancount = @@trancount;  
  3.       
  4.     if (@trancount=0) /*判断事务记数,根据情况确定使用保存点或者新建一个事务*/   
  5.         begin tran current_tran--当前事务点,rollback、commit都从这里开始    
  6.     else  
  7.         save tran current_tran  
[sql] view plain copy
 
  1. declare @trancount int --commit,rollback只控制本存储过程  
  2.     set @trancount = @@trancount;  
  3.       
  4.     if (@trancount=0) /*判断事务记数,根据情况确定使用保存点或者新建一个事务*/   
  5.         begin tran current_tran--当前事务点,rollback、commit都从这里开始   
  6.     else  
  7.         save tran current_tran  

.......

....做事去了

.......

 

[sql] view plaincopy
 
  1. if @error_code != 0 or @logErrorCode != 1  
  2.         begin  
  3.             rollback tran current_tran  
  4.             set @error_code = -1; -- 失败   
  5.         end  
  6.     else  
  7.         begin  
  8.             commit tran current_tran  
  9.             set @error_code = 1; -- 成功   
  10.          end  
[sql] view plain copy
 
  1. if @error_code != 0 or @logErrorCode != 1  
  2.         begin  
  3.             rollback tran current_tran  
  4.             set @error_code = -1; -- 失败  
  5.         end  
  6.     else  
  7.         begin  
  8.             commit tran current_tran  
  9.             set @error_code = 1; -- 成功  
  10.          end  

有没有问题?(current_tran是保存点哈,不明白的,后面有比较详细的介绍)

我用了好久了(在一个项目里面),可是突然有一天,也就是今天,它出事了。原因嘛,虽然写的是嵌套的,之前都没有嵌套调到过。

我在外围开了一个事务,再来调这个存储过程,当它 commit tran current_tran 时(rollback tran current_tran是不会有事的),会出什么错误?如果你不能很明确的告诉我,说明你还没有理解得深刻。做个选择吧?

1."...BEGIN 和 COMMIT 语句的数目不匹配。上一计数 = 0,当前计数 = 1。"

2."...BEGIN 和 COMMIT 语句的数目不匹配。上一计数 = 1,当前计数 = 0。

 

答案:【2】。

线索分析:我是在外部开了一个事务的,所以在未进入该存储过程以前@@trancount的值应该为1;进入时,save tran current_tran, @@trancount值没有变;完事的,执行commit tran current_tran,@@trancount的值应该为0;--所以,进入前,出来后,@@trancount值发生了改变,SqlServer不干了(原因,自己去想吧:拆散了begin tran 配对)。

怎么解决

 1.进入子事务前先记录@@trancount,我们用变量@trancount来记录。

 2. 提交子事务前,先判断之前的@trancount是否为0;为0表示"该事务"前没有事务调用,可以直接提交事务;不为0,表明进入该事务前已经有一个事务,该事务是子事务,不能提交。

[sql] view plaincopy
 
  1. -- 如果当前计数为0,则提交.    
  2.          -- 因为Commit tran ,@@TRANCOUNT会减1。嵌套事务时,调用该存在过程(作为子过程,此时@@TRANCOUNT > 0),   
  3.          -- 只是保存了tran, @@TRANCOUNT没有发生改变;直接Commit会使@@TRANCOUNT减1,会打破事务对(Begin Tran)   
  4.         if(@trancount = 0)  
  5.         begin  
  6.             commit tran current_tran  
  7.         end  
  8.         set @error_code = 1; -- 成功  
[sql] view plain copy
 
  1. -- 如果当前计数为0,则提交.   
  2.          -- 因为Commit tran ,@@TRANCOUNT会减1。嵌套事务时,调用该存在过程(作为子过程,此时@@TRANCOUNT > 0),  
  3.          -- 只是保存了tran, @@TRANCOUNT没有发生改变;直接Commit会使@@TRANCOUNT减1,会打破事务对(Begin Tran)  
  4.         if(@trancount = 0)  
  5.         begin  
  6.             commit tran current_tran  
  7.         end  
  8.         set @error_code = 1; -- 成功  

 

以上是关于数据库的问题,事务定义中,COMMIT语句和ROLLBACK语句的作用是啥?的主要内容,如果未能解决你的问题,请参考以下文章

SQL语言的组成

OraclePL/SQL块中使用事务

OraclePL/SQL块中使用事务

MySQL事务-ROLLBACK,COMMIT用法详解

php mysql commit之后还可以rollback么

EXECUTE 之后的事务计数表明 BEGIN 和 COMMIT 语句的数量不匹配。先前计数 = 1,当前计数 = 0