事务详解 .net

编辑:kasia

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

带事务的存储过程:
CREATE PROCEDURE dbo.SPTransaction
事务详解 <wbr>.net    (
事务详解 <wbr>.net    @UpdateID int,
事务详解 <wbr>.net    @UpdateValue nchar(50),
事务详解 <wbr>.net    @InsertID int,
事务详解 <wbr>.net    @InsertValue nchar(50)
事务详解 <wbr>.net    )
事务详解 <wbr>.netAS
事务详解 <wbr>.netbegin Tran
事务详解 <wbr>.netUpdate Region  Set RegionDescription=@UpdateValue where RegionID=@UpdateID
事务详解 <wbr>.net
事务详解 <wbr>.netinsert into Region Values (@InsertID,@InsertValue)
事务详解 <wbr>.net
事务详解 <wbr>.netdeclare @RegionError int
事务详解 <wbr>.netselect @RegionError=@@error
事务详解 <wbr>.netif(@RegionError=0)
事务详解 <wbr>.netCOMMIT Tran
事务详解 <wbr>.netelse
事务详解 <wbr>.netROLLBACK Tran
事务详解 <wbr>.netGO

执行带事务的存储过程:
/// <summary>
事务详解 <wbr>.net        /// SQL事务:
事务详解 <wbr>.net        /// </summary>
事务详解 <wbr>.net        public void SQLTran()
事务详解 <wbr>.net        {
事务详解 <wbr>.net            SqlConnection conn = new SqlConnection("Data Source=127.0.0.1;Initial Catalog=Northwind;Persist Security Info=True;User ID=sa;Password=123;");
事务详解 <wbr>.net            SqlCommand cmd = new SqlCommand();
事务详解 <wbr>.net            cmd.CommandText = "SPTransaction";
事务详解 <wbr>.net            cmd.CommandType = CommandType.StoredProcedure;
事务详解 <wbr>.net            cmd.Connection = conn;
事务详解 <wbr>.net            conn.Open();
事务详解 <wbr>.net            SqlParameter[] paras= new SqlParameter[]{
事务详解 <wbr>.net                                        new SqlParameter ("@UpdateID",SqlDbType.Int,32),
事务详解 <wbr>.net                                        new SqlParameter ("@UpdateValue",SqlDbType .NChar,50),
事务详解 <wbr>.net                                        new SqlParameter ("@InsertID",SqlDbType.Int ,32),
事务详解 <wbr>.net                                        new SqlParameter ("@InsertValue",SqlDbType.NChar ,50)};
事务详解 <wbr>.net            paras[0].Value = "2";
事务详解 <wbr>.net            paras[1].Value = "Update Value1";
事务详解 <wbr>.net            paras[2].Value = "6";
事务详解 <wbr>.net            paras[3].Value = "Insert Value1";
事务详解 <wbr>.net            foreach (SqlParameter para in paras )
事务详解 <wbr>.net            {
事务详解 <wbr>.net                cmd.Parameters.Add(para);
事务详解 <wbr>.net            }
事务详解 <wbr>.net            cmd.ExecuteNonQuery();   
事务详解 <wbr>.net        }
2 ADO.net事务
 Ado.net事务可能是大家一般都用的
 优点:简单,效率和数据库事务差不多。
 缺点:事务不能跨数据库,只能在一个数据库连接上。如果是两个数据库上就不能使用该事务了。
 Demo:
ADO.net事务:
/// <summary>
事务详解 <wbr>.net        /// 一般的ADO.net 事务
事务详解 <wbr>.net        /// </summary>
事务详解 <wbr>.net        public void ADONetTran1()
事务详解 <wbr>.net        {
事务详解 <wbr>.net            SqlConnection conn = new SqlConnection("Data Source=127.0.0.1;Initial Catalog=Northwind;Persist Security Info=True;User ID=sa;Password=123;");
事务详解 <wbr>.net            SqlCommand cmd = new SqlCommand();
事务详解 <wbr>.net            try
事务详解 <wbr>.net            {
事务详解 <wbr>.net                cmd.CommandText = "Update Region Set RegionDescription=@UpdateValue where RegionID=@UpdateID";
事务详解 <wbr>.net                cmd.CommandType = CommandType.Text;
事务详解 <wbr>.net                cmd.Connection = conn;
事务详解 <wbr>.net                conn.Open();
事务详解 <wbr>.net                SqlParameter[] paras = new SqlParameter[]{
事务详解 <wbr>.net                                        new SqlParameter ("@UpdateID",SqlDbType.Int,32),
事务详解 <wbr>.net                                        new SqlParameter ("@UpdateValue",SqlDbType .NChar,50)};
事务详解 <wbr>.net                paras[0].Value = "2";
事务详解 <wbr>.net                paras[1].Value = "Update Value12";
事务详解 <wbr>.net
事务详解 <wbr>.net                foreach (SqlParameter para in paras)
事务详解 <wbr>.net                {
事务详解 <wbr>.net                    cmd.Parameters.Add(para);
事务详解 <wbr>.net                }
事务详解 <wbr>.net                //开始事务
事务详解 <wbr>.net                cmd.Transaction = conn.BeginTransaction();
事务详解 <wbr>.net                cmd.ExecuteNonQuery();
事务详解 <wbr>.net
事务详解 <wbr>.net
事务详解 <wbr>.net                cmd.CommandText = "insert into Region values(@InsertID,@InsertValue)";
事务详解 <wbr>.net                cmd.CommandType = CommandType.Text;
事务详解 <wbr>.net
事务详解 <wbr>.net                paras = new SqlParameter[]{
事务详解 <wbr>.net                                        new SqlParameter ("@InsertID",SqlDbType.Int ,32),
事务详解 <wbr>.net                                        new SqlParameter ("@InsertValue",SqlDbType.NChar ,50)};
事务详解 <wbr>.net                paras[0].Value = "7";
事务详解 <wbr>.net                paras[1].Value = "Insert Value";
事务详解 <wbr>.net
事务详解 <wbr>.net                cmd.Parameters.Clear();
事务详解 <wbr>.net                foreach (SqlParameter para in paras)
事务详解 <wbr>.net                {
事务详解 <wbr>.net                    cmd.Parameters.Add(para);
事务详解 <wbr>.net                }
事务详解 <wbr>.net                
事务详解 <wbr>.net                cmd.ExecuteNonQuery();
事务详解 <wbr>.net                //提交事务
事务详解 <wbr>.net                cmd.Transaction.Commit();
事务详解 <wbr>.net            }
事务详解 <wbr>.net            catch
事务详解 <wbr>.net            {
事务详解 <wbr>.net                //回滚事务
事务详解 <wbr>.net                cmd.Transaction.Rollback();
事务详解 <wbr>.net                throw;
事务详解 <wbr>.net            }
事务详解 <wbr>.net            finally
事务详解 <wbr>.net            {
事务详解 <wbr>.net                conn.Close();
事务详解 <wbr>.net            }
事务详解 <wbr>.net
事务详解 <wbr>.net        }
3 TransactionScope事务
 TransactionScope事务类,它可以使代码块成为事务性代码。并自动提升为分布式事务
 优点:实现简单,同时能够自动提升为分布式事务
 Demo:
TransactionScope事务:
/// <summary>
事务详解 <wbr>.net        /// TransactionScope事务:可自动提升事务为完全分布式事务的轻型(本地)事务。 
事务详解 <wbr>.net        /// 使用时要保证MSDTC服务(控制分布事务)是开启的可以使用:net start msdtc命令开启服务;
事务详解 <wbr>.net        /// </summary>
事务详解 <wbr>.net        public void ADONetTran2()
事务详解 <wbr>.net        {
事务详解 <wbr>.net             SqlConnection conn = new SqlConnection("Data Source=127.0.0.1;Initial Catalog=Northwind;Persist Security Info=True;User ID=sa;Password=123;");
事务详解 <wbr>.net             SqlCommand cmd = new SqlCommand();
事务详解 <wbr>.net            try
事务详解 <wbr>.net            {
事务详解 <wbr>.net              
事务详解 <wbr>.net                using (System.Transactions.TransactionScope ts = new TransactionScope())
事务详解 <wbr>.net                {
事务详解 <wbr>.net                    
事务详解 <wbr>.net                    cmd.CommandText = "Update Region Set RegionDescription=@UpdateValue where RegionID=@UpdateID";
事务详解 <wbr>.net                    cmd.CommandType = CommandType.Text;
事务详解 <wbr>.net                    cmd.Connection = conn;
事务详解 <wbr>.net                    conn.Open();
事务详解 <wbr>.net                    SqlParameter[] paras = new SqlParameter[]{
事务详解 <wbr>.net                                        new SqlParameter ("@UpdateID",SqlDbType.Int,32),
事务详解 <wbr>.net                                        new SqlParameter ("@UpdateValue",SqlDbType .NChar,50)};
事务详解 <wbr>.net                    paras[0].Value = "2";
事务详解 <wbr>.net                    paras[1].Value = "Update Value12";
事务详解 <wbr>.net
事务详解 <wbr>.net                    foreach (SqlParameter para in paras)
事务详解 <wbr>.net                    {
事务详解 <wbr>.net                        cmd.Parameters.Add(para);
事务详解 <wbr>.net                    }
事务详解 <wbr>.net                    cmd.ExecuteNonQuery();
事务详解 <wbr>.net
事务详解 <wbr>.net
事务详解 <wbr>.net                    cmd.CommandText = "insert into Region values(@InsertID,@InsertValue)";
事务详解 <wbr>.net                    cmd.CommandType = CommandType.Text;
事务详解 <wbr>.net
事务详解 <wbr>.net                    paras = new SqlParameter[]{
事务详解 <wbr>.net                                        new SqlParameter ("@InsertID",SqlDbType.Int ,32),
事务详解 <wbr>.net                                        new SqlParameter ("@InsertValue",SqlDbType.NChar ,50)};
事务详解 <wbr>.net                    paras[0].Value = "8";
事务详解 <wbr>.net                    paras[1].Value = "Insert Value";
事务详解 <wbr>.net
事务详解 <wbr>.net                    cmd.Parameters.Clear();
事务详解 <wbr>.net                    foreach (SqlParameter para in paras)
事务详解 <wbr>.net                    {
事务详解 <wbr>.net                        cmd.Parameters.Add(para);
事务详解 <wbr>.net                    }
事务详解 <wbr>.net
事务详解 <wbr>.net                    cmd.ExecuteNonQuery();
事务详解 <wbr>.net                    //提交事务
事务详解 <wbr>.net                    ts.Complete();
事务详解 <wbr>.net                }
事务详解 <wbr>.net            }
事务详解 <wbr>.net            catch
事务详解 <wbr>.net            {
事务详解 <wbr>.net                throw;
事务详解 <wbr>.net            }
事务详解 <wbr>.net            finally
事务详解 <wbr>.net            {
事务详解 <wbr>.net                conn.Close();
事务详解 <wbr>.net            }
事务详解 <wbr>.net
事务详解 <wbr>.net        }

4 COM+事务
在分布式应用程序中,往往要同时操作多个数据库,使用数据库事务就不能满足业务的要求了。在COM+中,提供完整的事务处理服务。很方便处理多个数据库上的事务。
Demo:
COM+事务:
/// <summary>
事务详解 <wbr>.net        /// COM+事务
事务详解 <wbr>.net        /// </summary>
事务详解 <wbr>.net        public void ComTran()
事务详解 <wbr>.net        {
事务详解 <wbr>.net            SqlConnection conn = new SqlConnection("Data Source=127.0.0.1;Initial Catalog=Northwind;Persist Security Info=True;User ID=sa;Password=123;");
事务详解 <wbr>.net            SqlCommand cmd = new SqlCommand();
事务详解 <wbr>.net            ServiceConfig sc = new ServiceConfig();
事务详解 <wbr>.net
事务详解 <wbr>.net            //指定事务类型
事务详解 <wbr>.net            sc.Transaction = TransactionOption.Required;
事务详解 <wbr>.net            //设置启动跟踪
事务详解 <wbr>.net            sc.TrackingEnabled = true;
事务详解 <wbr>.net            //创建一个上下文,该上下文的配置由作为 cfg 参数传递的 ServiceConfig 对象来指定。
事务详解 <wbr>.net            //随后,客户端和服务器端的策略均被触发,如同发生了一个方法调用。
事务详解 <wbr>.net            //接着,新的上下文被推至上下文堆栈,成为当前上下文
事务详解 <wbr>.net            ServiceDomain.Enter(sc);
事务详解 <wbr>.net            try
事务详解 <wbr>.net            {
事务详解 <wbr>.net                    cmd.CommandText = "Update Region Set RegionDescription=@UpdateValue where RegionID=@UpdateID";
事务详解 <wbr>.net                    cmd.CommandType = CommandType.Text;
事务详解 <wbr>.net                    cmd.Connection = conn;
事务详解 <wbr>.net                    conn.Open();
事务详解 <wbr>.net                    SqlParameter[] paras = new SqlParameter[]{
事务详解 <wbr>.net                                        new SqlParameter ("@UpdateID",SqlDbType.Int,32),
事务详解 <wbr>.net                                        new SqlParameter ("@UpdateValue",SqlDbType .NChar,50)};
事务详解 <wbr>.net                    paras[0].Value = "2";
事务详解 <wbr>.net                    paras[1].Value = "Update Value22";
事务详解 <wbr>.net
事务详解 <wbr>.net                    foreach (SqlParameter para in paras)
事务详解 <wbr>.net                    {
事务详解 <wbr>.net                        cmd.Parameters.Add(para);
事务详解 <wbr>.net                    }
事务详解 <wbr>.net                    cmd.ExecuteNonQuery();
事务详解 <wbr>.net
事务详解 <wbr>.net
事务详解 <wbr>.net                    cmd.CommandText = "insert into Region values(@InsertID,@InsertValue)";
事务详解 <wbr>.net                    cmd.CommandType = CommandType.Text;
事务详解 <wbr>.net
事务详解 <wbr>.net                    paras = new SqlParameter[]{
事务详解 <wbr>.net                                        new SqlParameter ("@InsertID",SqlDbType.Int ,32),
事务详解 <wbr>.net                                        new SqlParameter ("@InsertValue",SqlDbType.NChar ,50)};
事务详解 <wbr>.net                    paras[0].Value = "9";
事务详解 <wbr>.net                    paras[1].Value = "Insert Value";
事务详解 <wbr>.net
事务详解 <wbr>.net                    cmd.Parameters.Clear();
事务详解 <wbr>.net                    foreach (SqlParameter para in paras)
事务详解 <wbr>.net                    {
事务详解 <wbr>.net                        cmd.Parameters.Add(para);
事务详解 <wbr>.net                    }
事务详解 <wbr>.net
事务详解 <wbr>.net                    cmd.ExecuteNonQuery();
事务详解 <wbr>.net
事务详解 <wbr>.net                    //提交事务
事务详解 <wbr>.net                    ContextUtil.SetComplete();
事务详解 <wbr>.net            }
事务详解 <wbr>.net            catch
事务详解 <wbr>.net            {
事务详解 <wbr>.net                //回滚事务
事务详解 <wbr>.net                ContextUtil.SetAbort();
事务详解 <wbr>.net                throw;
事务详解 <wbr>.net            }
事务详解 <wbr>.net            finally
事务详解 <wbr>.net            {
事务详解 <wbr>.net                conn.Close();
事务详解 <wbr>.net                //触发服务器端的策略,随后触发客户端的策略,如同一个方法调用正在返回。
事务详解 <wbr>.net                //然后,当前上下文被弹出上下文堆栈,调用 Enter 时正在运行的上下文成为当前的上下文。
事务详解 <wbr>.net                ServiceDomain.Leave();
事务详解 <wbr>.net            }
事务详解 <wbr>.net
事务详解 <wbr>.net        }
在.net中还有些也能进行事务处理,如web Service中

需要特别补充的是:
如果你使用的是分布事务(TransactionScope事务和COM+事务),在默认情况下你是要重新配置安装SQL Server数据库服务器和访问数据库的客户端的.(如果没有配置运行会出现以下错误:该伙伴事务管理器已经禁止了它对远程/网络事务的支持。 (异常来自 HRESULT:0x8004D025)
)下面是MSDN上关于配置分布式事务的一段原话:
配置分布式事务
要 启用分布式事务,可能需要通过网络启用 MS DTC,以便在使用应用了最新的 Service Pack 的较新操作系统(例如 Windows XP 或 Windows 2003)时使用分布式事务。如果启用了 Windows 防火墙(Windows XP Service Pack 2 的默认设置),必须允许 MS DTC 服务使用网络或打开 MS DTC 端口。
实际怎么配置呢,经过我的实际使用:大致如下: 打开'控制面板'->'管理工具'->'组件服务',点开'组件服务'->'计算机'->'我的电脑',在'我的电脑'上右击属 性,点'MSDTC',然后点'安全性配置'。作为数据库的服务器的配置如下:
事务详解 <wbr>.net

而访问数据库的客户端的配置和服务器端的稍有些差别:

事务详解 <wbr>.net

在设置完上面的还有使防火墙MS DTC 服务使用网络或打开 MS DTC 端口:运行netsh firewall set allowedprogram %windir%\system32\msdtc.exe MSDTC enable命令就可以了

转载于:https://www.cnblogs.com/zhangchenliang/archive/2013/05/29/3105347.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值