sql事务,何时会用到Rollback()方法

秋的红果实 2016-04-21 09:58:23
如题,在哪种场合需要用到Rollback()方法,也就是,在哪种场合,需要以显式的方式,写上Rollback()语句

如下类似MSDN的代码,我们知道,发生Exception,数据库会自动回滚,无需写上Rollback();
那么,什么场合会用到Rollback()方法?

SqlTransaction Tran=null;
using(SqlConnection conn=new……)
{
try
{
conn.Open();
SqlCommand comm = conn.CreateCommand();
Tran = conn.BeginTransaction("SpecifyTran");
//操作table1
//操作tble2
//……

Tran.Commit();
}
catch
{
//……
}
}
...全文
1604 18 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
首先 rollback 必须在事务里面。也就是说,如果你把 autocommit 设为 false,之后调用 rollback,大部分驱动都会报错。 然后就是,一些驱动在关闭时默认rollback,所以如果你要执行一个事务之后就关闭,就不用调用了,当然调用了也是个 no-op,已知的有 jdbc mysql 和 py mysql。 另外一些驱动的默认行为是 commit,这个要留意一些。
江南小鱼 2016-04-21
  • 打赏
  • 举报
回复
一个大事务包含四步操作,各个步骤间以执行结果为导向进行传递: 前三步成功了(数据库做了相应改动),第四步失败了,显然前三步的改动要恢复原状(事务回滚
RubenLuLu 2016-04-21
  • 打赏
  • 举报
回复
那种场合需要用到Rollback()?。 你理解了Rollback()的意义,你的业务中需要时自然就需要啊!
卧_槽 2016-04-21
  • 打赏
  • 举报
回复
数据库事务只是保证数据操作原子性吧?
  • 打赏
  • 举报
回复
一般都是显示的指示rollback,这样数据库那边能立即回滚,而不是等你的代码出了生命周期后才回滚,要知道数据库事务是有锁的
  • 打赏
  • 举报
回复
当过程结束而GC自动销毁 DbTransaction 对象时 --> 当Using 模块结束而 Dbconnection执行 Dispose 时 如果写了 using,自动执行dispose,就会及时回滚没有 Commit 的事务。
  • 打赏
  • 举报
回复
引用 4 楼 Yokeqi 的回复:
MSDN好像不仅提供了Commit的范例,也有提供RollBack的范例啊。 我们这边是会在Catch中手动写上RollBack的 https://msdn.microsoft.com/zh-cn/library/zayx5s0h%28v=vs.100%29.aspx
msdn 上的例子,也就是演示这个技术语句。实际上这个例子很瞎掰。你不写 Rollback,当过程结束而GC自动销毁 DbTransaction 对象时,就自动 Rollback了。用不着你手动写 Rollback。 msdn 的例子只是从技术出发(而技术其实是最低级的编程设计环节),给你一个”立刻执行 Rollback 啊“的例子。它才不告诉你没有必要多余去手写代码。
  • 打赏
  • 举报
回复
大部分的”手动回滚“代码可能都在代码中写
throw new ........
这样的代码,这就会造成回滚。但是如果你的业务逻辑就有”放弃“的流程,那么你就没有必要用什么 throw 了,直接应该写 rollback了。 另外,在更宽的设计范围内,”放弃“动作并不是 rollback。例如一个人购买一张机票,在付款之前他放弃了,那么这张机票就会重新回到”可销售的机票“池中,也就是说所谓”放弃“是一系列业务操作,而不是什么数据库回滚操作。在这类业务程序设计中,如果你只是用数据库事务的概念来理解”放弃“,那么你可能造成很多尴尬的结果。例如一个人迟迟不付款,例如操作员去上厕所了,那么是不是上万、数十万的售票点的电脑都要死锁去等待它一个售票点commit或者rollback呢? 只是用数据库的概念来生搬硬套到业务流程处理上,是很扯的,会造成完全不在同一个设计频道上的情况。只有你详细研究了业务操作流程图,知道哪些是瞬间的技术事务操作,哪些是长时间的业务事务操作,你才能判断这是一个技术问题还是业务问题。只有很低级的技术问题,才用数据库的技术观念去考虑。
枫0子K 2016-04-21
  • 打赏
  • 举报
回复
MSDN好像不仅提供了Commit的范例,也有提供RollBack的范例啊。 我们这边是会在Catch中手动写上RollBack的 https://msdn.microsoft.com/zh-cn/library/zayx5s0h%28v=vs.100%29.aspx
枫0子K 2016-04-21
  • 打赏
  • 举报
回复
我感觉楼主有点钻入牛角尖。 1. 我觉得没有用到的时候可以了解这个东西的用法,但是没必要纠结什么时候可以用到(个人而言,遇到适用情况就才会想到还有这东西可用)。 2. 因为BeginTran跟Commit之间还有很多逻辑,有时候掺杂一些业务逻辑或者互斥逻辑的时候,不就可以手动调用RollBack来回滚这些修改吗?给开发者提供更自由的发挥空间。(所以上面说楼主有点钻牛角尖) 例如业务要求Update一条语句失败的时候(返回0行被修改)就要提示用户是否继续,当用户点击取消的时候要取消本次修改。这个时候如果没有RollBack方法,那你就哭吧。
xuzuning 2016-04-21
  • 打赏
  • 举报
回复
在你认为需要放弃当前操作的时候 如果是发生Exception,那么你连 sql 指令都会弄错,还谈什么事务呢?
  • 打赏
  • 举报
回复
你的业务逻辑设计中有那个流程,你就有编程需求了。 编程设计要从领域模型的业务出发,编程是很低级的工作,不要纠结在技术中去拼凑应用,你要忘掉技术、去想问题。
tcmakebest 2016-04-21
  • 打赏
  • 举报
回复
楼主是缺乏一点想象力, 自己回滚数据操作就是 对数据有一定的要求, 但这种要求又不能提前判断, 需要在操作了一些数据之后再判断, 这时候就要撤销已经进行的数据操作.
mlxwl2013 2016-04-21
  • 打赏
  • 举报
回复
什么时候会用到RollBack?当sql命令执行没有出错,而是逻辑上需要RollBack时,需要显式调用RollBack。例如:往数据库更新一些记录,然后算出一个结果,程序中判断这个结果是否如预期那样,如果不是就显式调用RollBack回滚。
mlxwl2013 2016-04-21
  • 打赏
  • 举报
回复
“当发出Exception时,自动回滚;而且此时不用在catch里显式的写上Rollback();“ 这个说法是错误的。 不存在”自动回滚“之说,没有commit不代表自动回滚。 实际上如果在一个事务中执行某条sql错误,且没有执行rollback,那么事务就没有结束,直到你执行了数据连接的Close或Dispose方法。 如果事务没有结束,相关的资源就没有释放,比如锁等。
秋的红果实 2016-04-21
  • 打赏
  • 举报
回复
引用 8 楼 starfd 的回复:
一般都是显示的指示rollback,这样数据库那边能立即回滚,而不是等你的代码出了生命周期后才回滚,要知道数据库事务是有锁的
要是发生异常,就不用显示写了哇?也不知道往哪里写 事务的锁,请说详细些
秋的红果实 2016-04-21
  • 打赏
  • 举报
回复
感谢各位的回复。 以前只用过:当发出Exception时,自动回滚;而且此时不用在catch里显式的写上Rollback();,于是就有疑问了,既然造了Rollback()方法,一定其用武之地。没用过别的。没时间钻牛角尖,请不要误会 现在确认下,按照大家说的,这么用行吗? if(用户要回滚=="是") { myTransaction.Rollback(); //sql操作不提交给sql服务器,数据库中数据没变化 } else { myTransaction.Commit(); //sql操作提交给sql服务器,数据库中数据有变化 }
枫0子K 2016-04-21
  • 打赏
  • 举报
回复
引用 6 楼 sp1234 的回复:
[quote=引用 4 楼 Yokeqi 的回复:] MSDN好像不仅提供了Commit的范例,也有提供RollBack的范例啊。 我们这边是会在Catch中手动写上RollBack的 https://msdn.microsoft.com/zh-cn/library/zayx5s0h%28v=vs.100%29.aspx
msdn 上的例子,也就是演示这个技术语句。实际上这个例子很瞎掰。你不写 Rollback,当过程结束而GC自动销毁 DbTransaction 对象时,就自动 Rollback了。用不着你手动写 Rollback。 msdn 的例子只是从技术出发(而技术其实是最低级的编程设计环节),给你一个”立刻执行 Rollback 啊“的例子。它才不告诉你没有必要多余去手写代码。[/quote] 请看#8楼解释
引用 8 楼 starfd 的回复:
一般都是显示的指示rollback,这样数据库那边能立即回滚,而不是等你的代码出了生命周期后才回滚,要知道数据库事务是有锁的
我也觉得为了使代码更易读,应该显示指示RollBack,而不是炫耀你知道出了生命周期后会自动回滚。 另外从设计的单一、封闭性来说,也应该是有Begin就有End吧。

111,112

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧