zoukankan      html  css  js  c++  java
  • .net中的4种事务总结 .

    在一个MIS系统中,没有用事务那就绝对是有问题的,要么就只有一种情况:你的系统实在是太小了,业务业务逻辑有只要一步执行就可以完成了。因此掌握事务处理的方法是很重要,进我的归类在.net中大致有以下4种事务处理的方法。大家可以参考一下,根据实际选择适当的事务处理。
    1 SQL事务
        sql事务是使用SQL server自身的事务:在存储过程中直接使用Begin Tran,Rollback Tran,Commit Tran实现事务:
    优点:执行效率最佳
    限制:事务上下文仅在数据库中调用,难以实现复杂的业务逻辑。
    Demo:(所有demo,都以SQL Server自带的Northwind数据的表Region为例)

    View Code
    CREATE PROCEDURE dbo.SPTransaction
        (
        @UpdateID int,
        @UpdateValue nchar(50),
        @InsertID int,
        @InsertValue nchar(50)
        )
    AS
    begin Tran
    Update Region  Set RegionDescription=@UpdateValue where RegionID=@UpdateID
    
    insert into Region Values (@InsertID,@InsertValue)
    
    declare @RegionError int
    select @RegionError=@@error
    if(@RegionError=0)
    COMMIT Tran
    else
    ROLLBACK Tran
    GO
    
            /// <summary>
            /// SQL事务:
            /// </summary>
            public void SQLTran()
            {
                SqlConnection conn = new SqlConnection("Data Source=127.0.0.1;Initial Catalog=Northwind;Persist Security Info=True;User ID=sa;Password=123;");
                SqlCommand cmd = new SqlCommand();
                cmd.CommandText = "SPTransaction";
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Connection = conn;
                conn.Open();
                SqlParameter[] paras= new SqlParameter[]{
                                            new SqlParameter ("@UpdateID",SqlDbType.Int,32),
                                            new SqlParameter ("@UpdateValue",SqlDbType .NChar,50),
                                            new SqlParameter ("@InsertID",SqlDbType.Int ,32),
                                            new SqlParameter ("@InsertValue",SqlDbType.NChar ,50)};
                paras[0].Value = "2";
                paras[1].Value = "Update Value1";
                paras[2].Value = "6";
                paras[3].Value = "Insert Value1";
                foreach (SqlParameter para in paras )
                {
                    cmd.Parameters.Add(para);
                }
                cmd.ExecuteNonQuery();   
            }

    2 ADO.net事务
       Ado.net事务可能是大家一般都用的
     优点:简单,效率和数据库事务差不多。
     缺点:事务不能跨数据库,只能在一个数据库连接上。如果是两个数据库上就不能使用该事务了。
    Demo:

    View Code
    /// <summary>
            /// 一般的ADO.net 事务
            /// </summary>
            public void ADONetTran1()
            {
                SqlConnection conn = new SqlConnection("Data Source=127.0.0.1;Initial Catalog=Northwind;Persist Security Info=True;User ID=sa;Password=123;");
                SqlCommand cmd = new SqlCommand();
                try
                {
                    cmd.CommandText = "Update Region Set RegionDescription=@UpdateValue where RegionID=@UpdateID";
                    cmd.CommandType = CommandType.Text;
                    cmd.Connection = conn;
                    conn.Open();
                    SqlParameter[] paras = new SqlParameter[]{
                                            new SqlParameter ("@UpdateID",SqlDbType.Int,32),
                                            new SqlParameter ("@UpdateValue",SqlDbType .NChar,50)};
                    paras[0].Value = "2";
                    paras[1].Value = "Update Value12";
    
                    foreach (SqlParameter para in paras)
                    {
                        cmd.Parameters.Add(para);
                    }
                    //开始事务
                    cmd.Transaction = conn.BeginTransaction();
                    cmd.ExecuteNonQuery();
    
    
                    cmd.CommandText = "insert into Region values(@InsertID,@InsertValue)";
                    cmd.CommandType = CommandType.Text;
    
                    paras = new SqlParameter[]{
                                            new SqlParameter ("@InsertID",SqlDbType.Int ,32),
                                            new SqlParameter ("@InsertValue",SqlDbType.NChar ,50)};
                    paras[0].Value = "7";
                    paras[1].Value = "Insert Value";
    
                    cmd.Parameters.Clear();
                    foreach (SqlParameter para in paras)
                    {
                        cmd.Parameters.Add(para);
                    }
                    
                    cmd.ExecuteNonQuery();
                    //提交事务
                    cmd.Transaction.Commit();
                }
                catch
                {
                    //回滚事务
                    cmd.Transaction.Rollback();
                    throw;
                }
                finally
                {
                    conn.Close();
                }
    
            }

    3 TransactionScope事务
      TransactionScope事务类,它可以使代码块成为事务性代码。并自动提升为分布式事务
     优点:实现简单,同时能够自动提升为分布式事务
    Demo:

    View Code
    /// <summary>
            /// TransactionScope事务:可自动提升事务为完全分布式事务的轻型(本地)事务。 
            /// 使用时要保证MSDTC服务(控制分布事务)是开启的可以使用:net start msdtc命令开启服务;
            /// </summary>
            public void ADONetTran2()
            {
                 SqlConnection conn = new SqlConnection("Data Source=127.0.0.1;Initial Catalog=Northwind;Persist Security Info=True;User ID=sa;Password=123;");
                 SqlCommand cmd = new SqlCommand();
                try
                {
                  
                    using (System.Transactions.TransactionScope ts = new TransactionScope())
                    {
                        
                        cmd.CommandText = "Update Region Set RegionDescription=@UpdateValue where RegionID=@UpdateID";
                        cmd.CommandType = CommandType.Text;
                        cmd.Connection = conn;
                        conn.Open();
                        SqlParameter[] paras = new SqlParameter[]{
                                            new SqlParameter ("@UpdateID",SqlDbType.Int,32),
                                            new SqlParameter ("@UpdateValue",SqlDbType .NChar,50)};
                        paras[0].Value = "2";
                        paras[1].Value = "Update Value12";
    
                        foreach (SqlParameter para in paras)
                        {
                            cmd.Parameters.Add(para);
                        }
                        cmd.ExecuteNonQuery();
    
    
                        cmd.CommandText = "insert into Region values(@InsertID,@InsertValue)";
                        cmd.CommandType = CommandType.Text;
    
                        paras = new SqlParameter[]{
                                            new SqlParameter ("@InsertID",SqlDbType.Int ,32),
                                            new SqlParameter ("@InsertValue",SqlDbType.NChar ,50)};
                        paras[0].Value = "8";
                        paras[1].Value = "Insert Value";
    
                        cmd.Parameters.Clear();
                        foreach (SqlParameter para in paras)
                        {
                            cmd.Parameters.Add(para);
                        }
    
                        cmd.ExecuteNonQuery();
                        //提交事务
                        ts.Complete();
                    }
                }
                catch
                {
                    throw;
                }
                finally
                {
                    conn.Close();
                }
    
            }

    4 COM+事务
      在分布式应用程序中,往往要同时操作多个数据库,使用数据库事务就不能满足业务的要求了。在COM+中,提供完整的事务处理服务。很方便处理多个数据库上的事务。
    Demo:

    View Code
    /// <summary>
            /// COM+事务
            /// </summary>
            public void ComTran()
            {
                SqlConnection conn = new SqlConnection("Data Source=127.0.0.1;Initial Catalog=Northwind;Persist Security Info=True;User ID=sa;Password=123;");
                SqlCommand cmd = new SqlCommand();
                ServiceConfig sc = new ServiceConfig();
    
                //指定事务类型
                sc.Transaction = TransactionOption.Required;
                //设置启动跟踪
                sc.TrackingEnabled = true;
                //创建一个上下文,该上下文的配置由作为 cfg 参数传递的 ServiceConfig 对象来指定。
                //随后,客户端和服务器端的策略均被触发,如同发生了一个方法调用。
                //接着,新的上下文被推至上下文堆栈,成为当前上下文
                ServiceDomain.Enter(sc);
                try
                {
                        cmd.CommandText = "Update Region Set RegionDescription=@UpdateValue where RegionID=@UpdateID";
                        cmd.CommandType = CommandType.Text;
                        cmd.Connection = conn;
                        conn.Open();
                        SqlParameter[] paras = new SqlParameter[]{
                                            new SqlParameter ("@UpdateID",SqlDbType.Int,32),
                                            new SqlParameter ("@UpdateValue",SqlDbType .NChar,50)};
                        paras[0].Value = "2";
                        paras[1].Value = "Update Value22";
    
                        foreach (SqlParameter para in paras)
                        {
                            cmd.Parameters.Add(para);
                        }
                        cmd.ExecuteNonQuery();
    
    
                        cmd.CommandText = "insert into Region values(@InsertID,@InsertValue)";
                        cmd.CommandType = CommandType.Text;
    
                        paras = new SqlParameter[]{
                                            new SqlParameter ("@InsertID",SqlDbType.Int ,32),
                                            new SqlParameter ("@InsertValue",SqlDbType.NChar ,50)};
                        paras[0].Value = "9";
                        paras[1].Value = "Insert Value";
    
                        cmd.Parameters.Clear();
                        foreach (SqlParameter para in paras)
                        {
                            cmd.Parameters.Add(para);
                        }
    
                        cmd.ExecuteNonQuery();
    
                        //提交事务
                        ContextUtil.SetComplete();
                }
                catch
                {
                    //回滚事务
                    ContextUtil.SetAbort();
                    throw;
                }
                finally
                {
                    conn.Close();
                    //触发服务器端的策略,随后触发客户端的策略,如同一个方法调用正在返回。
                    //然后,当前上下文被弹出上下文堆栈,调用 Enter 时正在运行的上下文成为当前的上下文。
                    ServiceDomain.Leave();
                }
    
            }
  • 相关阅读:
    学习总结(二十六)
    学习总结(二十五)
    在知乎学习怎么参加工作
    连分数系列
    Kalman Filter
    五子棋的学习
    Dijkstra
    三等分角、化圆为方、倍立方体
    女朋友走丢数学模型
    传染病模型
  • 原文地址:https://www.cnblogs.com/songjiali/p/2760568.html
Copyright © 2011-2022 走看看