您的位置:首页 > 运维架构 > 网站架构

asp.net 事务的处理,dts 的设置,asp.net三种事务处理方法,三层架构,微软企业库,动软生成器生成的代码下如何使用事务

2012-04-18 18:06 1176 查看
在上一篇文章中,由于我需要同时往订单表和订单详情表插入数据(订单详情表里面的订单编号是订单表的id主键自动生成的值),由于牛腩购物网是用动软生成器,微软企业库的三层架构,在DAL层已经封装好了代码,所以我用到的是TransactionScope来实现的事务处理。

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

应用程序通过在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()方法


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::CommitITransaction::Abort方法结束事务时不会自动启动另一事务。
在ADO中,对Connection对象使用BeginTrans方法可启动隐式事务。若要结束该事务,可调用该Connection对象的CommitTransRollbackTrans方法。(这个也就是上面的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
%>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐
章节导航