当前位置:编程学习 > C#/ASP.NET >>

请高手回答: 一个关于RollBack()的问题一直没得到很好的回答.

     SqlTransaction myTrans;

     myTrans = myConnection.BeginTransaction();
     myCommand.Connection = myConnection;
     myCommand.Transaction = myTrans;

  try{   
           //第一条SQL语句
            myCommand.CommandText = "insert into db_user (Id,UserPwd) values('111,'123456')";
            myCommand.ExecuteNonQuery();

           //第二条SQL语句
            myCommand.CommandText = "insert into db_user (Id,UserPwd) values('222,'123456')";
            myCommand.ExecuteNonQuery();
            myTrans.Commit();
      }
      catch(Exception e)
      {
       myTrans.Rollback();//这里有什么用呀??
       }
      finally
      {
        myConnection.Close();
             
      }

问题描述: 
    (1) 如果两条SQL语句中第二条出问题,那么应该不会执行Commit语句,转而去执行myTrans.Rollback();第一条SQL中的数据不会插入. 这个很容易理解.
    (2)但是我发现如果把myTrans.Rollback();注释掉,也就是不写回滚操作, 第一条SQL中的数据也不会插入到表中.
    (3) 也就是说写与不写RollBack()都一回事,只要打开了事务就可以了: myTrans = myConnection.BeginTransaction();.  
结论: 
     也就是说.Net中提供的RollBack()方法根本就没用处.? 
    请大家编程试试,不要乱说,省的让大家搞不明白...,我十分清楚事务的概念,请大家不要对这个解释.



--------------------编程问答-------------------- 开启事务后,如果没有Commit,就不会提交,因为报错后没有执行Commit --------------------编程问答-------------------- 你不写的话它自己就隐士的调用 而已,,写了就显示的调用 ,仅此而已
--------------------编程问答-------------------- 上家答非所问. 不要乱回帖! --------------------编程问答-------------------- 哦.是上上家. --------------------编程问答-------------------- 不一定出现错误才要回滚
可以是满足一定条件时需要回滚,执行RollBack() --------------------编程问答-------------------- 这个问题其实早就已经说过了,通过添加数据库监视,你会发现只要加了事物在执行SQL过程发生异常,默认状态下是回滚的,而且还能监视到事物回滚的事件,除非语句正常执行,而不管你是不是明显的设置了myTrans.Rollback();

ADO.NET事务实际上是把事务上下文传递到数据库层,如果事务中发生一个错误,数据库会自动回滚。在你的错误处理代码中,每次调用Rollback()方法之前检查事务对象是否存在是一种良好的习惯。这样的一个例子是当一个死锁发生的同时,数据库正在执行自动回滚。   
--------------------编程问答--------------------
引用 3 楼  的回复:
上家答非所问. 不要乱回帖!

你才在乱回帖。。。。你看懂了没有????????? --------------------编程问答-------------------- 正常地写上
using(var con= GetConnection())
{
  var tran= con.BeginTransaction();
  ......
  tran.Commit();
}

这就行了。

用不着些什么 Rollback! --------------------编程问答--------------------
引用楼主  的回复:
也就是说.Net中提供的RollBack()方法根本就没用处.?  


这是初学者的问题。

专业的开人员应该结合.net源代码去学习,而不是“靠揣测.net而过活”。

在SqlConnection被GC销毁时,会在 Dispose方法中自动调用其 Close方法。而这个Close做什么,你自己看吧。 --------------------编程问答--------------------
引用楼主  的回复:
也就是说.Net中提供的RollBack()方法根本就没用处.?  


这是初学者的问题。

专业的开人员应该结合.net源代码去学习,而不是“靠揣测.net而过活”。

在SqlConnection被GC销毁时,会在 Dispose方法中自动调用其 Close方法。而这个Close做什么,你自己看吧。 --------------------编程问答-------------------- 大家还是没有回答到点子上, 或者说跟我理解的是一样的.就是没必要有RollBack(). 你们做做测试,不要拿你们自以为的经验来回帖.要知道你们的经验都是复制了别人的. 
    问题其实很简单:
    (1)如果开通了事务,并且出了异常,那就没有Commit,干嘛还要有RollBack()?,
    (2)如果没异常,那就commit了,RollBack()也没用.
    所有没必要RollBack(),或者说这个功能没用.
    所有大家最后把这个RollBack()功能解释清楚,千万别自以为是. --------------------编程问答-------------------- 如果开通了事务,并且出了异常,那就没有Commit?你怎么知道没有提交?
当你第一条数据正常,而异常出现在第二句的时候,那么第一条是能正常添加入库的,但是由于捕获了异常,那么数据库就自动回滚了,就造成了全部没有入库的假象(这可以通过监视来得到证明,至少自增ID的确是+了1个的,这就说明第一条的确曾经入库过)

虽然我没研究过这其中的源码究竟是如何封装或者处理的,但是我们完全可以通过一些测试来查看处理过程,就像sp1234说的,SqlConnection被GC销毁时,会在 Dispose方法中自动调用其 Close方法。而这个Close做什么

这些你得研究源码了,c#本身就高度抽象,高度封装,我们更在意的是这个东西它能做什么。

个人看法。 --------------------编程问答--------------------
引用 8 楼  的回复:
正常地写上C# code
using(var con= GetConnection())
{
  var tran= con.BeginTransaction();
  ......
  tran.Commit();
}

这就行了。

用不着些什么 Rollback!

这个代码就是我遇到的问题,,我之前因为没有 commit();然后数据插入就有问题了。。
LZ这个代码的情况假如向下面啊:
你的数据插入都完全正确,但在Try中 出现异常,那么也会到catch中去。。这个也是有这样的需求的。。
Commit()的作用了就是判断事物的正确与否,正确的话就 插入数据,错误就rollback --------------------编程问答-------------------- 我知道开启事务后,第一条SQL中数据会隐式地插入数据库中,这个可以在第一条SQL和第二条SQL之间,插入一条读取表中全部记录的SQL看到第一条SQL中的数据已经隐式地插入数据库中. 但在数据库中没看到相应的记录,也就是说没提交. 
   只是我不清楚,如果第二条SQL语句出现异常,把catch语句中的RollBack()也注释掉和不注释,都能够回滚. 也就是说出了异常,那么就会自动执行这个RollBack().这在微软的MSDN中看到了这个解释. 
   现在从大家的回复和微软的解释,可以得出如下结论:出现异常,会自动回滚.
   但是又有下述问题:
     (1)  它自动回滚是发生在什么时候?难道发生异常,就回滚?这岂不是很荒谬,如果不是SQL异常,而是其它异常,我们肯定不会去回滚的,而是报其它异常就够了. 
     (2)  还有怎么就找不到取消自动回滚的语句,而采取手动回滚呢?例如像我例子中的显示回滚. --------------------编程问答--------------------
引用 14 楼  的回复:
我知道开启事务后,第一条SQL中数据会隐式地插入数据库中,这个可以在第一条SQL和第二条SQL之间,插入一条读取表中全部记录的SQL看到第一条SQL中的数据已经隐式地插入数据库中. 但在数据库中没看到相应的记录,也就是说没提交. 
   只是我不清楚,如果第二条SQL语句出现异常,把catch语句中的RollBack()也注释掉和不注释,都能够回滚. 也就是说出了异常,那么就会自动执行这个Ro……

问题 1:你说的错误的.......sql语句没有错误那么就会插入 的...假如你的catch中没有rollback();但是sql语句正确..但是在执行 非sql的某个东西出现异常时 .....还是会插入数据的.......
这个就是问题2的所在也... --------------------编程问答--------------------
引用 6 楼  的回复:
这个问题其实早就已经说过了,通过添加数据库监视,你会发现只要加了事物在执行SQL过程发生异常,默认状态下是回滚的,而且还能监视到事物回滚的事件,除非语句正常执行,而不管你是不是明显的设置了myTrans.Rollback();

ADO.NET事务实际上是把事务上下文传递到数据库层,如果事务中发生一个错误,数据库会自动回滚。在你的错误处理代码中,每次调用Rollback()方法之前检查事务对象……

楼主自己没看懂吧,人家已经说的很清楚了 --------------------编程问答-------------------- 1.不管你做不做,.net框架都会帮你做,及时.net框架不做(断电),oracle(或其它)也会帮你做;
2.事务回滚:当事务修改表中数据的时候,该数据修改前的值(即前影像)会存放在回滚段中,当用户回滚事务(ROLLBACK)时,ORACLE将会利用回滚段中的数据前影像来将修改的数据恢复到原来的值。  --------------------编程问答-------------------- rollback()是有作用的。建议你问度娘事务处理的概念。rollback()就是说你的所有sql语句,要么全部执行,要么全部不执行。就像入库一样,入库了以后入库前的数量减少,库存量增加。若中间sql语句有一句出错了,没有用rollback的话,入库前的数量减少了,但库存量却没有增加。所以,语句必须要么全部执行,要么全部不执行。
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,