asp.net 事务的处理,dts 的设置,asp.net三种事务处理方法,三层架构,微软企业库,动软生成器生成的代码下如何使用事务
2012-04-18 18:06
1176 查看
在上一篇文章中,由于我需要同时往订单表和订单详情表插入数据(订单详情表里面的订单编号是订单表的id主键自动生成的值),由于牛腩购物网是用动软生成器,微软企业库的三层架构,在DAL层已经封装好了代码,所以我用到的是TransactionScope来实现的事务处理。
1:dts的设置在运行里面输入dcomcnfg
在.NET中使用TransactionScope进行事务控制时,必须设置客户端和服务器端的MSDTC安全配置如下:否则只能在数据库服务器上可以正常使用,客户端使用会报错“事务已被隐式或显式提交,或已终止。”。
然后在我们的项目上,先添加引用,并在代码中usingSystem.Transactions;
知识点:asp.net三种事务处理
三层结构下,数据访问层与业务逻辑分离。从对象关系角度看,业务逻辑层的对象依赖于数据访问层。.net平台提供了ado.net对数据库进行操作,connection对象提供了对database连接与transaction的功能。在分层结构下,数据访问层处理了对数据库的操作,实现了domain每一个对象与database的方法。例如对象Customer,提供CustomerDAO.Add(),CustomerDAO.Update()等等的方法,每一个方法都会引用独立的connection对象。业务层直接调用CustomerDAO的方法。connection对象对业务层是close状态,业务层不能访问到并且控制ado.net提供的transaction。在不破坏分层体系结构前提下一般有三种方式来实现。
SQL事务处理、ADO.NET事务处理、COM+事务处理(也就是文章开头的TransactionScope)
SQL事务处理:SqlTransaction
应用程序通过在SqlConnection对象上调用BeginTransaction来创建SqlTransaction对象。对SqlTransaction对象执行与该事务关联的所有后续操作(例如提交或中止该事务)。
你可以写在sql里面,例如你写一个存储过程,在插入订单表的时候,也同时插入订单详情表
SQL脚本使用BEGINTRANSACTION、COMMITTRANSACTION、COMMITWORK、ROLLBACKTRANSACTION或ROLLBACKWORKTransact-SQL语句定义显式事务。
BEGINTRANSACTION
标记显式连接事务的起始点。
COMMITTRANSACTION或COMMITWORK
如果没有遇到错误,可使用该语句成功地结束事务。该事务中的所有数据修改在数据库中都将永久有效。事务占用的资源将被释放。
ROLLBACKTRANSACTION或ROLLBACKWORK
用来清除遇到错误的事务。该事务修改的所有数据都返回到事务开始时的状态。事务占用的资源将被释放。
ADO.NET事务处理:
在ADO.NETSqlClient托管提供程序中,对SqlConnection对象使用BeginTransaction方法可以启动一个显式事务。若要结束事务,可以对SqlTransaction对象调用Commit()或Rollback()方法
1:dts的设置在运行里面输入dcomcnfg
在.NET中使用TransactionScope进行事务控制时,必须设置客户端和服务器端的MSDTC安全配置如下:否则只能在数据库服务器上可以正常使用,客户端使用会报错“事务已被隐式或显式提交,或已终止。”。
然后在我们的项目上,先添加引用,并在代码中usingSystem.Transactions;
最后,我贴出我的代码。
我先通过intorderid=orderdao.Add(order);来获取订单表自动生成的ID,并且接下来,我循环购物车,把购物车里面的商品,添加到订单详情表里面
最后我scope.Complete();这样就提交了事务,由于我的事务是放在using里面的,所以会自动释放我用到的事务,主要代码都是放在try里面的,如果报错,那么位于
using里面的事务范围,就会回滚,不执行操作。(我刚开始没有设置DTS,也报错了,也回滚了)
//开始插入到两张表,用到事务。需要在项目上添加引用System.Transactions,而且还需要写usingSystem.Transactions;
using(TransactionScopescope=newTransactionScope())//这里有创建一个TransactionScope表示事务性代码,因为用到using会自动释放
{
try
{
//如果这里报错的话,整个scope都会自动回滚的
intorderid=orderdao.Add(order);
if(orderid>0)
{
DAL.OrderdetailsDAOoddao=newDAL.OrderdetailsDAO();
foreach(Model.ShopItemiteminsc.GetItemList())
{
oddao.Add(newModel.Orderdetails{//这里是添加订单详情表
orderid=orderid,
price=item.price,
proid=item.proid,
quantity=item.quantity
});
}
scope.Complete();
}
else
{
Utility.Tool.alert("订单添加失败,请联系管理员",this.Page);
}
}
catch(Exceptionre)
{
Response.Write("事务错误,具体报错信息是:"+re.Message);
Response.End();
}
}
知识点:asp.net三种事务处理
三层结构下,数据访问层与业务逻辑分离。从对象关系角度看,业务逻辑层的对象依赖于数据访问层。.net平台提供了ado.net对数据库进行操作,connection对象提供了对database连接与transaction的功能。在分层结构下,数据访问层处理了对数据库的操作,实现了domain每一个对象与database的方法。例如对象Customer,提供CustomerDAO.Add(),CustomerDAO.Update()等等的方法,每一个方法都会引用独立的connection对象。业务层直接调用CustomerDAO的方法。connection对象对业务层是close状态,业务层不能访问到并且控制ado.net提供的transaction。在不破坏分层体系结构前提下一般有三种方式来实现。
SQL事务处理、ADO.NET事务处理、COM+事务处理(也就是文章开头的TransactionScope)
SQL事务处理:SqlTransaction
应用程序通过在
你可以写在sql里面,例如你写一个存储过程,在插入订单表的时候,也同时插入订单详情表
SQL脚本使用BEGINTRANSACTION、COMMITTRANSACTION、COMMITWORK、ROLLBACKTRANSACTION或ROLLBACKWORKTransact-SQL语句定义显式事务。
BEGINTRANSACTION
标记显式连接事务的起始点。
COMMITTRANSACTION或COMMITWORK
如果没有遇到错误,可使用该语句成功地结束事务。该事务中的所有数据修改在数据库中都将永久有效。事务占用的资源将被释放。
ROLLBACKTRANSACTION或ROLLBACKWORK
用来清除遇到错误的事务。该事务修改的所有数据都返回到事务开始时的状态。事务占用的资源将被释放。
ADO.NET事务处理:
在ADO.NETSqlClient托管提供程序中,对SqlConnection对象使用BeginTransaction方法可以启动一个显式事务。若要结束事务,可以对SqlTransaction对象调用Commit()或Rollback()方法
publicvoidExecuteNoneSql(stringp_sqlstr,paramsstring[]p_cmdStr)
{
using(SqlConnectionconn=newSqlConnection(p_sqlstr))
{
Conn.Open();
SqlCommandcmd=newSqlCommand();
cmd.Connection=conn;
SqlTransactiontrans=null;
trans=conn.BeginTransaction();//初始化事务
cmd.Transaction=trans;//绑定事务
try
{
for(inti=0;i<p_cmdStr.Length;i++)
{
cmd.CommandText=p_cmdStr[i];
cmd.CommandType=CommandType.Text;
cmd.ExecuteNonQuery();
}
trans.Commit();//提交
}
catch(SqlExceptione)
{
if(trans!=null)trans.Rollback();//回滚
else
{//写日志}
}
}
}
带保存点回滚示例:
using(SqlConnectionconn=newSqlConnection(p_sqlstr))
{
conn.Open();
SqlCommandcmd=newSqlCommand();
cmd.Connection=conn;
SqlTransactiontrans=conn.BeginTransaction("table");
cmd.Transaction=trans;
try
{
cmd.CommandText="Insertintotable_name1values(values1,values2,....)";
cmd.CommandType=CommandType.Text;
cmd.ExecuteNonQuery();
cmd.CommandText="Insertintotable_name2values(values1,values2,....)";
cmd.CommandType=CommandType.Text;
cmd.ExecuteNonQuery();
trans.Save("table1");
cmd.CommandText="Insertintotable_name2values(values1,values2,....)";
cmd.CommandType=CommandType.Text;
cmd.ExecuteNonQuery();
trans.Save("table2");
trans.Commit();
}
catch
{
try
{trans.Rollback("table2");}
catch
{
try{trans.Rollback("table1");}
catch{trans.Rollback("table");}
}
}
}
三者性能比较:
性能排名:SQL事务处理>ADO.NET事务处理>COM+事务处理(TransactionScope)
SQL事务处理只需要进行一次数据库交互,优点就是速度很快,而且所有逻辑包含在一个单独的调用中,与应用程序独立,缺点就是与数据库绑定。
ADO.NET需要2n次数据库往返,但相对而言,ADO.NET事务处理性能比SQL事务处理低很少,在一般应用程序中可以忽略。而且ADO.NET事务处理将事务处理与数据库独立,增加了程序的移植性。而且他也可以横跨多个数据库,不过他对于数据库的类型要求一致。
COM+事务处理性能最低,主要因为COM+本身的一些组件需要内存开销。但COM+可以横跨各种数据存储文件,这一点功能是前两者所无法媲美的。
另外:如果是asp的话,还可以在OLEDB中使用显式事务。调用ITransactionLocal::StartTransaction方法可启动事务。如果将fRetaining设置为FALSE,通过调用ITransaction::Commit或ITransaction::Abort方法结束事务时不会自动启动另一事务。
在ADO中,对Connection对象使用BeginTrans方法可启动隐式事务。若要结束该事务,可调用该Connection对象的CommitTrans或RollbackTrans方法。(这个也就是上面的asp的事务的方法)
在asp的时候,就用到过事务,但是这个事务是和一个connection链接对象在一起的
<%
'asp事务处理。
'测试数据库为sqlserver,服务器为本机,数据库名为test,表名为a,两个字段id(int)主键标识,num(int)
setconn=server.CreateObject("adodb.connection")
strConn="provider=sqloledb.1;persistsecurityinfo=false;uid=sa;pwd=sa;InitialCatalog=test;DataSource=."
conn.OpenstrConn
'以上代码建立数据库连接
conn.BeginTrans'事务开始
strSql1="updateasetnum=1000whereid=24"'第一个sql语句为update。(语法正确)
strSql2="insertintoa(num)values('a')"'第二个sql语句为错误的sql语句
strSql3="insertintoa(num)values(33333)"'第三个sql语句为正确的sql语句
callconn.execute(strSql1)
callconn.execute(strSql2)
callconn.execute(strSql3)
ifconn.Errors.Count=0then
conn.CommitTrans'如果没有conn错误,则执行事务提交
else
conn.RollbackTrans'否则回滚
endif
%>
相关文章推荐
- Asp.net 在三层架构中事务的使用实例代码
- ASP.NET中使用后端代码注册脚本 生成JQUERY-EASYUI的界面错位的解决方法
- [转]微软代码示例:ASP.NET 2.0 三层架构应用程序教程系列
- 方法代码ASP.NET MVC如何使用Ajax的辅助方法
- 在xml布局文件中,我们既可以设置px,也可以设置dp(或者dip)。一般情况下,我们都会选择使用dp,这样可以保证不同屏幕分辨率的机器上布局一致。但是在代码中,如何处理呢?很多控件的方法中都只提供了
- C#编译器优化那点事 c# 如果一个对象的值为null,那么它调用扩展方法时为甚么不报错 webAPI 控制器(Controller)太多怎么办? .NET MVC项目设置包含Areas中的页面为默认启动页 (五)Net Core使用静态文件 学习ASP.NET Core Razor 编程系列八——并发处理
- Asp.net 在三层架构中事务的使用
- ASP.NET中使用后端代码注册脚本 生成JQUERY-EASYUI的界面错位的解决方法
- 项目开发中的一些注意事项以及技巧总结 基于Repository模式设计项目架构—你可以参考的项目架构设计 Asp.Net Core中使用RSA加密 EF Core中的多对多映射如何实现? asp.net core下的如何给网站做安全设置 获取服务端https证书 Js异常捕获
- ADO.NET Entity Framework 如何:使用 EdmGen.exe 生成对象层代码
- 如何在ASP.NET中制作Web用户自定义控件,并在aspx页面中使用它的方法和属性?
- ASP.NET动态加载Js代码到Head标签中(三种方法)
- asp.net(c#) 使用Rex正则来生成字符串数组的代码
- 在javascript中使用(读取、设置)Asp.net服务器的属性、方法和事件
- ELMAH (ASP.NET错误日志处理)使用方法
- 微软ASP.Net Ajax:使用AJAX直接调用后台页面类方法
- ASP.NET 4.0 与 Entity Framework 4-第四篇-Entity Framework在三层架构中的使用
- 在ASP.NET 2.0中,有时候需要对ASP.NET生成的HTML代码进行处理,或者是保存成静态文件。ASP.NET 提供了直接将请求保存成文件的方法:HttpRequest.SaveAs方法。下面这个方法就是在ASP.NET 2.0中得到ASP.NET
- IIS如何处理Asp.net请求和Asp.net页面生命周期方法