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

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

    1:  dts的设置   在运行里面输入   dcomcnfg

    在.NET中使用TransactionScope进行事务控制时,必须设置客户端和服务器端的MSDTC安全配置如下:否则只能在数据库服务器上可以正常使用,客户端使用会报错“事务已被隐式或显式提交,或已终止。 ”。

    image

    然后在我们的项目上,先添加引用 ,并在代码中 using System.Transactions;

    image

     
    最后,我贴出我的代码。
    我先通过 int orderid = orderdao.Add(order);  来获取订单表自动生成的ID,并且接下来,我循环购物车,把购物车里面的商品,添加到 订单详情表里面
    最后我scope.Complete();   这样就提交了事务,由于我的事务是放在 using里面的,所以会自动释放我用到的事务,主要代码都是放在try里面的,如果报错,那么位于
    using里面的 事务范围,就会回滚,不执行操作。(我刚开始没有设置DTS,也报错了,也回滚了)
     
    //开始插入到两张表,用到事务。需要在项目上添加引用 System.Transactions ,而且还需要写 using System.Transactions;
                using (TransactionScope scope = new TransactionScope())  //这里有创建一个  TransactionScope 表示事务性代码,因为用到using会自动释放
                {
                    try
                    {
                        //如果这里报错的话,整个scope 都会自动 回滚的
                        int orderid = orderdao.Add(order);
                        if (orderid > 0)
                        {
                            DAL.OrderdetailsDAO oddao = new DAL.OrderdetailsDAO();
                            foreach (Model.ShopItem item in sc.GetItemList())
                            {
                                oddao.Add(new Model.Orderdetails {  //这里是添加订单详情表
                                orderid=orderid,
                                price=item.price,
                                proid=item.proid,
                                quantity=item.quantity
                                });
                            }
                            scope.Complete();
                        }
                        else
                        {
                            Utility.Tool.alert("订单添加失败,请联系管理员", this.Page);
                        }
                        
                    }
                    catch (Exception re)
                    {
                        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 脚本使用 BEGIN TRANSACTION、COMMIT TRANSACTION、COMMIT WORK、ROLLBACK TRANSACTION 或 ROLLBACK WORK Transact-SQL 语句定义显式事务。

    BEGIN TRANSACTION

    标记显式连接事务的起始点。

    COMMIT TRANSACTION 或 COMMIT WORK

    如果没有遇到错误,可使用该语句成功地结束事务。该事务中的所有数据修改在数据库中都将永久有效。事务占用的资源将被释放。

    ROLLBACK TRANSACTION 或 ROLLBACK WORK

    用来清除遇到错误的事务。该事务修改的所有数据都返回到事务开始时的状态。事务占用的资源将被释放。

    ADO.NET事务处理:

    在 ADO.NET SqlClient 托管提供程序中,对 SqlConnection 对象使用 BeginTransaction 方法可以启动一个显式事务。若要结束事务,可以对 SqlTransaction 对象调用 Commit()Rollback() 方法


    public
    void ExecuteNoneSql(string p_sqlstr, params string[] p_cmdStr) { using (SqlConnection conn = new SqlConnection(p_sqlstr)) { Conn.Open(); SqlCommand cmd = new SqlCommand(); cmd.Connection = conn; SqlTransaction trans = null; trans = conn.BeginTransaction(); //初始化事务 cmd.Transaction = trans; //绑定事务 try { for (int i = 0; i < p_cmdStr.Length; i++) { cmd.CommandText = p_cmdStr[i]; cmd.CommandType = CommandType.Text; cmd.ExecuteNonQuery(); } trans.Commit(); //提交 } catch (SqlException e) { if (trans != null) trans.Rollback(); //回滚 else {//写日志} } } }

    带保存点回滚示例:


    using
    (SqlConnection conn = new SqlConnection(p_sqlstr)) { conn.Open(); SqlCommand cmd = new SqlCommand(); cmd.Connection = conn; SqlTransaction trans = conn.BeginTransaction("table"); cmd.Transaction = trans; try { cmd.CommandText = "Insert into table_name1 values(values1,values2,....)"; cmd.CommandType = CommandType.Text; cmd.ExecuteNonQuery(); cmd.CommandText = "Insert into table_name2 values(values1,values2,....)"; cmd.CommandType = CommandType.Text; cmd.ExecuteNonQuery(); trans.Save("table1"); cmd.CommandText = "Insert into table_name2 values(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的话,还可以在 OLE DB 中使用显式事务。调用 ITransactionLocal::StartTransaction 方法可启动事务。如果将 fRetaining 设置为 FALSE,通过调用 ITransaction::CommitITransaction::Abort 方法结束事务时不会自动启动另一事务。

    在 ADO 中,对 Connection 对象使用 BeginTrans 方法可启动隐式事务。若要结束该事务,可调用该 Connection 对象的 CommitTransRollbackTrans 方法。(这个也就是上面的asp的事务的方法)

    在asp的时候,就用到过事务,但是这个事务是和一个 connection 链接对象在一起的

    <%
    'asp事务处理。
    '测试数据库为sql server,服务器为本机,数据库名为test,表名为a,两个字段id(int)主键标识,num(int)
    set conn=server.CreateObject("adodb.connection") 
    strConn="provider=sqloledb.1;persist security info=false;uid=sa;pwd=sa;Initial Catalog=test;Data Source=."
    conn.Open strConn
    '以上代码建立数据库连接
    conn.BeginTrans '事务开始
    strSql1="update a set num=1000 where id=24" '第一个sql语句为update。(语法正确)
    strSql2="insert into a(num) values('a')" '第二个sql语句为错误的sql语句
    strSql3="insert into a(num) values(33333)" '第三个sql语句为正确的sql语句 
    
    
    call conn.execute(strSql1)  
    call conn.execute(strSql2)  
    call conn.execute(strSql3)  
    
    
    if conn.Errors.Count=0 then  
          conn.CommitTrans  '如果没有conn错误,则执行事务提交
    else 
          conn.RollbackTrans '否则回滚
    end if
    %>
    
  • 相关阅读:
    Codeforces 611C. New Year and Domino 动态规划
    POJ2585 Window Pains 拓扑排序
    HDOJ1242 Rescue(营救) 搜索
    codeforces 数字区分 搜索
    ZOJ2412 Farm Irrigation(农田灌溉) 搜索
    hdu 4389 X mod f(x) 数位dp
    hdu 4734 F(x) 数位dp
    Codeforces Beta Round #51 D. Beautiful numbers 数位dp
    hdu 3652 B-number 数位dp
    bzoj 1026: [SCOI2009]windy数 数位dp
  • 原文地址:https://www.cnblogs.com/iceicebaby/p/2455728.html
Copyright © 2011-2022 走看看