• 全部
  • .NET Framework
  • ASP
  • Web Services
  • .NET互联网桌面应用
  • VB
  • 图表区
  • 分析与设计
  • 组件/控件开发
  • AppLauncher
  • 问答

关于三层结构如何处理事处的问题

tnt8csdn2000 2004-04-08 02:20:52
做一个项目,用WEB、业务、数据访问、存储过程、数据库这样的结构。
有表a,表b﹔存程过程sp_InsertA,sp_InsertB。
现在有这样的一个需要:一种业务操作需要用sp_InsertA对a表插入记录Ra、用sp_InsertB对B表插入数条记录(Ra1,Ra2……..),记录数不定。Ra1,Ra2…….是以Ra的PK作为FK的。如果B表的其中一条记录RaX插入失败,则必须清理B表中已经插入的Ra1---Ra(X-1),并把a表中的Ra删除。

各位高手,在数据访问层用事务写一个调用sp_InsertA,sp_InsertB进行这样的操作?
...全文
121 点赞 收藏 18
写回复
18 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
erist 2004-04-10
我参考了微软的SQLHelper.cs,但是它只支持语句的事务,在使用存储过程时工没有使用事务。

我看现在的2.0版本,无论是语句还是存储过程都有事务处理的。
回复
erist 2004-04-10
微软有文档介绍说:事务可以放在数据访问层,但不要作为事务处理的根,事务处理的根一般放在业务逻辑层。
回复
billy_zh 2004-04-10
可参考MS的ADO.NET的数据访问指南,
他有两种解决方案:
1。自己处理事务,就像楼上各位说的那样;
2。使用.net的自动事务;
如果使用自动事务的,建议还是多加一个事务控制对象。
比方说业务A完成inserta, 业务B完成insertb,
那么此时应该建立一个事务控制对象Transobj, 此对象具有自动事务!
然后在这个对象的一个方法insertab内调用业务a的inserta, 业务b的insertb,
成功则完成事务,失败则回滚事务。
这样就可以让业务对象不直接处理事务了。
回复
tnt8csdn2000 2004-04-10
是用事务处理,cansee()写法我会用,但是我使用的DataAccess需要被包装起来为业务层编写人员提供服务,不需要让他们关心内部的方法,外部只需要传入存储过程名与参数,其它的不用管。而且最重要的是InsertB的执行次数并不确定,可能是1次,也可能是100次。如果都只执行一次就用InsertAB了,在数据库服务器上执行比用语句传递要好得多。我参考了微软的SQLHelper.cs,但是它只支持语句的事务,在使用存储过程时工没有使用事务。
回复
wuxiaohai123 2004-04-09
用一个事务来处理吧,一旦出错就rollback,这是一段示例代码:ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/cpref/html/frlrfSystemDataSqlClientSqlTransactionClassTopic.htm

回复
活靶子哥哥 2004-04-09
Microsoft® SQL Server™ 2000 中的许多管理活动是通过一种称为系统存储过程的特殊过程执行的。系统存储过程在 master 数据库中创建并存储,带有 sp_ 前缀。可从任何数据库中执行系统存储过程,而无需使用 master 数据库名称来完全限定该存储过程的名称。

强烈建议您不要创建以 sp_ 为前缀的存储过程。SQL Server 始终按照下列顺序查找以 sp_ 开头的存储过程:

在 master 数据库中查找存储过程。


根据所提供的任何限定符(数据库名称或所有者)查找该存储过程。


如果未指定所有者,则使用 dbo 作为所有者查找该存储过程。
因此,虽然当前数据库中可能存在带 sp_ 前缀的用户创建的存储过程,但总会先检查 master 数据库(即使该存储过程已用数据库名称限定)。



重要 如果用户创建的存储过程与系统存储过程同名,则永远不执行用户创建的存储过程。

详见
mk:@MSITStore:C:\Program%20Files\Microsoft%20SQL%20Server\80\Tools\Books\createdb.chm::/cm_8_des_07_7yw5.htm
回复
活靶子哥哥 2004-04-09
这么多了
我在发一点言
存储过程不要用sp开头
回复
sqlserver触发器
回复
smartcreater 2004-04-09
cansee() 的方法只能rollBack sp_InsertA 的操作,

应稍做修改:
// 开始事务
myTrans = myConnection.BeginTransaction();
myCommand.Connection = myConnection;
myCommand.Transaction = myTrans;

try
{
myCommand.CommandText = "sp_InsertA";
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.ExecuteNonQuery();
myCommand.CommandText = "sp_InsertB";
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.ExecuteNonQuery();

......
}
catch(Exception e)
{
// 发生错误,回滚未执行事务以前的数据
myTrans.Rollback();
}
finally
{
myConnection.Close();
}
回复
liuyong_lll 2004-04-09
你可以再写一个存储过程,这个里边包含了两个存储过程的执行,根据影响行数来判断,如果存在问题,则回滚.....

当然上边的情况也是很值得考虑的^_^
回复
Level2002Level 2004-04-09
begin tran T1
table A insert Ra
table B insert Ra1
table B insert Ra1
table B insert Ra1
...
if @@error<>0 then
rollback tran T1
else
commit tran T1
回复
lveight 2004-04-09
同意cansee() 的做法!
回复
kensou28 2004-04-09
虽然没做过 帮顶~ 随便想想应该是使用事务.
回复
matu 2004-04-09
up!
回复
pierven 2004-04-09
用一个事务来处理吧,一旦出错就rollback,这是一段示例代码:ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/cpref/html/frlrfSystemDataSqlClientSqlTransactionClassTopic.htm
回复
cansee 2004-04-09
public void RunSqlTransaction(string myConnString)
{
SqlConnection myConnection = new SqlConnection(myConnString);
myConnection.Open();

SqlCommand myCommand = myConnection.CreateCommand();
SqlTransaction myTrans;

// 开始事务
myTrans = myConnection.BeginTransaction();
myCommand.Connection = myConnection;
myCommand.Transaction = myTrans;

try
{
myCommand.CommandText = "sp_InsertA";
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.ExecuteNonQuery();
......
}
catch(Exception e)
{
// 发生错误,回滚未执行事务以前的数据
myTrans.Rollback();
}
finally
{
myConnection.Close();
}
}
回复
yinleiwudi 2004-04-09
把2个合二为一不是更好吗?新建一个sp_InsertAB
回复
tnt8csdn2000 2004-04-09
up
回复
相关推荐
发帖
.NET技术社区
创建于2007-09-28

5.8w+

社区成员

.NET技术交流专区
申请成为版主
帖子事件
创建了帖子
2004-04-08 02:20
社区公告
暂无公告