讨论一下事务的处理方式,请星星们来看看.

tfrtfr 2010-03-17 08:52:50
今天和写存储过程的同事为事务处理问题有点争论,请大家一起来讨论讨论。
存储过程:
过程A
{
...
Update ...
...
Update ..
...
}
程序:
调用存储过程A();

这里存在一个事务问题,大家觉得应该应该把代码改造成:
开始事务;
调用存储过程A;
提交事务。
错误时回滚事务;

还是存储过程内部应该有事务处理自己的回滚,即
过程A
{
开始事务
...
Update ...
...
Update ..
...
没有错误提交事务
有错误回滚事务
}
两种方式都能解决问题,不过大家来讨论一下哪种方式更规范,如果能说出为什么最好.

(注意,这是只调一个过程的情况,调多个过程的话程序里肯定要事务处理,这个不用讨论。)


...全文
241 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
lugsbbs 2010-03-18
  • 打赏
  • 举报
回复
来学习学习
canshishidao 2010-03-18
  • 打赏
  • 举报
回复
认真学习一下,要坚持
gsq_0912 2010-03-18
  • 打赏
  • 举报
回复
在存儲過程中,使用事務更合情合理!
guoyichao 2010-03-18
  • 打赏
  • 举报
回复
这个就是性能和重构之间的取舍关系了,从dba的角度来看数据库操作的性能是第一位的,从开发的角度来看程序的可重构性更重要,如果你是开发那就应该牺牲一点db的操作性能来提高程序的重构能力。
canshishidao 2010-03-18
  • 打赏
  • 举报
回复
我觉得应该遵循一个准则:自己的事情自己处理,包括异常、事务的处理。

支持第二种方法!
tfrtfr 2010-03-18
  • 打赏
  • 举报
回复
众说纷纭啊。
算了,程序里加上事务吧。
不过我还是觉得不合理,本来存储过程自己可以做的事,现在所有调用的地方都得先开始事务-〉调用过程-〉结束事务,工作量明显增加。作为公用方法,调用的地方肯定不止一个。
至少我看到SqlServer里的系统存储过程都会有事务去处理自己对库的改变的,不知道其他数据库是不是这样。
  • 打赏
  • 举报
回复
google了一下,中文的关于RaiseError的文章还真是少的可怜。但是你去读任何一本关于T-SQL权威书籍,都应该重点讲到这个东西。

搜了一篇文章作为参考:http://www.easewe.com/Article/Document/333.htm
  • 打赏
  • 举报
回复
我的建议,走统一的“抛出异常”机制,不要返回什么错误标志。
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 tfrtfr 的回复:]
呵呵,主要是以前合作的同事都是习惯于存储过程里有事务,处理好内部的.
所以单独调用一个过程的代码都是不开事务的.
现在的同事存储过程里是没有事务的,内部不管是什么错误(可能是逻辑上的),返回了的错误标志,外面就要回滚事务.
写了多年的代码习惯要改,而且被认为我代码没写好...我就没仔细看他们写的存储过程,我把它作为黑盒看待的,不知道里面是没事务的.
[/Quote]
其实这类问题完全应该到SQL Server板块去问。(但不知道那里会不会回答清楚)

T-SQL 语言使用 RaiseError 语句抛出异常给调用者,这样你的程序以及存储过程全都不用管什么Trans,因为SQL Server自动为每一个请求开启了一个事务,而RaiseError时就会自动回滚。

你“现在的同事”返回了错误标志,既然使用这么原始的方式,那么就把工作推卸给其它人了。
RYAN--333 2010-03-18
  • 打赏
  • 举报
回复
学习 .
mayonglong 2010-03-17
  • 打赏
  • 举报
回复
倾向于第二种~
wonsoft 2010-03-17
  • 打赏
  • 举报
回复
第二种好些吧,这样封装更有独立性,让事务就封装在过程中,使用起来更简单明了。
特别 2010-03-17
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 vrhero 的回复:]

没什么不合理的...

首先,出了问题必须反馈调用者...在面向对象的设计中,多数时候下层只应该负责执行和反馈,由上层来控制...
[/Quote]
严重同意
vrhero 2010-03-17
  • 打赏
  • 举报
回复
没什么不合理的...

首先,出了问题必须反馈调用者...在面向对象的设计中,多数时候下层只应该负责执行和反馈,由上层来控制...
特别 2010-03-17
  • 打赏
  • 举报
回复

[Quote=引用 11 楼 sdfkfkd 的回复:]

如果你这个存储过程A表达了一个完整的业务逻辑,而且在可预见的将来(两三年内)不会改变,个人倾向于第一种方式,
如果只是一个业务逻辑的一部分,显而易见地应该使用第二种方式
一般的原则是如果该存储过程不会被包含在另一个业务逻辑(或者事务中),可以自己启动事务,要不然由调用方启动事务
综上所述,如果不确定的话,应该采用第二种方案,灵活可控。
[/Quote]
上面的第一种是指在存储过程中控制事务,第二种是指在ADO.NET中控制事务
特别 2010-03-17
  • 打赏
  • 举报
回复
如果你这个存储过程A表达了一个完整的业务逻辑,而且在可预见的将来(两三年内)不会改变,个人倾向于第一种方式,
如果只是一个业务逻辑的一部分,显而易见地应该使用第二种方式
一般的原则是如果该存储过程不会被包含在另一个业务逻辑(或者事务中),可以自己启动事务,要不然由调用方启动事务
综上所述,如果不确定的话,应该采用第二种方案,灵活可控。
tfrtfr 2010-03-17
  • 打赏
  • 举报
回复
To vrhero:
我仅指过程对自己内部做的事的处理.譬如过程里有两个Update语句,执行第一个没有问题,当执行第二个的时候发生错误。这时候对一个update的回滚是应该存储过程做,还是返回一个错误,由调用者判断,然后回滚呢。
我理解为一个方法应该自己做好自己的事情,自己内部已经出错了,不处理回滚,而依赖调用者,是不是有点不合理?
vrhero 2010-03-17
  • 打赏
  • 举报
回复
不能一概而论...

数据库事务只是事务控制方法的一种,一定要清楚每种事务方法都是性能、可维护性及架构设计的综合因素决定的...

数据库事务的优点是良好的性能,但可维护性较差...另外对DBMS特性依赖度过高,某些场景复杂度过高,如跨越多个可识别事务的管理器的分布式事务...

一般来说,如果不是对性能有特别要求不应该由存储过程控制事务而应该由调用者控制事务...当然如果你不是面向对象的开发就无所谓了,全写在存储过程里也不是不可以...
wiki14 2010-03-17
  • 打赏
  • 举报
回复
用的是第二种处理方式。
showlie 2010-03-17
  • 打赏
  • 举报
回复
我觉得应该遵循一个准则:自己的事情自己处理,包括异常、事务的处理。

支持第二种方法!
加载更多回复(6)

111,120

社区成员

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

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

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