System.Transactions 命名空间中除了上一节中提到的基于 Transaction 类的显式编程模型,还提供使用 TransactionScope 类的隐式编程模型,它与显示编程模型相比,更加方便简单,它也是MSDN中建议使用的编程模型。

下面,我们基于TransactionScope类实现上一节银行转帐的例程。

示例代码:

(1)SqlHelper.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Configuration;

using MySql.Data.MySqlClient;

using System.Transactions;

using System.Data;

 

namespace 事务处理

{

    public class SqlHelper

    {

        public static string GetConnection()

        {

            string connStr = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;

            return connStr;

        }

 

        public static int ExecuteNonQuery(string sql, params MySqlParameter[] parameters)

        {

            int result = -1;

            using (MySqlConnection conn = new MySqlConnection(GetConnection()))

            {

                conn.Open();

                

                using (MySqlCommand cmd = conn.CreateCommand())

                {

                    cmd.CommandText = sql;

                    cmd.Parameters.AddRange(parameters);

                    result = cmd.ExecuteNonQuery();

                }

            }

            return result;

        }

 

        public static DataTable ExecuteDataTable(string sql, params MySqlParameter[] parameters)

        {

            using (MySqlConnection conn = new MySqlConnection(GetConnection()))

            {

                using (MySqlCommand cmd = conn.CreateCommand())

                {

                    cmd.CommandText = sql;

                    cmd.Parameters.AddRange(parameters);

                    using (MySqlDataAdapter da = new MySqlDataAdapter(cmd))

                    {

                        using (DataSet ds = new DataSet())

                        {

                            da.Fill(ds);

                            return ds.Tables[0];

                        }

                    }

                }

            }

        }

    }

 

}

(2)Bankaccountn.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using MySql.Data.MySqlClient;

using System.Data;

using System.Transactions;

 

namespace 事务处理

{

    public class Bankaccountn

    {

        public Bankaccountn(string bankaccountnId)

        {

            string sql = @"SELECT * FROM Bankaccountn WHERE BankaccountnId=@BankaccountnId;";

            DataTable dt = SqlHelper.ExecuteDataTable(sql, new MySqlParameter("@BankaccountnId", bankaccountnId));

            if (dt.Rows.Count <= 0)

            {

                throw new Exception("账户不存在!");

            }

            else if (dt.Rows.Count > 1)

            {

                throw new Exception("异常信息:有重名的账户存在!");

            }

            else

            {

                this.bankaccountnId = dt.Rows[0]["BankaccountnId"] as string;

                this.UserName = dt.Rows[0]["UserName"] as string;

                this.Balance = Convert.ToDecimal(dt.Rows[0]["Balance"]);

            } 

        }

 

        private string bankaccountnId;

        public string UserName

        { 

            get; 

            private set; 

        }

        public decimal Balance

        {

            get;

            private set;

        }

        

        protected int Update()

        {

            string sql = @"UPDATE bankaccountn SET UserName = @UserName,Balance = @Balance 

                           WHERE BankaccountnId= @BankaccountnId;";

            return SqlHelper.ExecuteNonQuery(sql, new MySqlParameter("@BankaccountnId", this.bankaccountnId), new MySqlParameter("@UserName", this.UserName), new MySqlParameter("@Balance", this.Balance));

 

        }

        public void Epend( decimal money)

        {

            this.Balance -= money;

            this.Update();

        }

        public void Income(decimal money)

        {

            this.Balance += money;

            this.Update();

            

        }

        public bool HiddenTransferOfAccount(string incomeBankaccountnId, decimal money)

        {

            bool result = true;

            using (TransactionScope scope = new TransactionScope())

            {

                try

                {

                    Bankaccountn incomeBankaccountn = new Bankaccountn(incomeBankaccountnId);

                    incomeBankaccountn.Income(money); //收款账户入账

                    this.Epend(money); //付款账户支出

                    scope.Complete();

                }

                catch (Exception ex)

                {

                    //这里写做异常信息的记录的代码

                    result = false;

                }

            }

            return result;

        }

    }

    

}

(3)测试代码

Bankaccountn one = new Bankaccountn("6666660123456789");

if (one.HiddenTransferOfAccount("6666669876543210", 200M))

{

    Response.Write("<script>alert('转账成功')</script>");

}

else

{

    Response.Write("<script>alert('转账失败')</script>");

}

代码分析:

使用TransactionScope 之后,事务管理器会 预执行代码,直至Complete()处,如果过程没有出错,这通知事务管理器去提交,如果错误就不提交,保证了整个执行过程的一致性。

但,在使用隐式编程模型时应注意以下几点:

1)要确保参与事务的资源(如连接的打开等)的全登记放在TransactionScope 实例化对象之后,调用Complete()方法之前。

2)从TransactionScope 实例化到调用Complete()方法之间的代码,不要吃掉异常。

 

 

using (TransactionScope scope = new TransactionScope())

{

    try

    {

        //要确保参与事务的资源全部登记在这个位置(如连接的打开等)

         Bankaccountn incomeBankaccountn = new Bankaccountn(incomeBankaccountnId);

         incomeBankaccountn.Income(money); //收款账户入账

         this.Epend(money); //付款账户支出

         scope.Complete();

    }

    catch (Exception ex)

    {

         //捕获异常要在这个位置

          result = false;

    }

}


基于TransactionScope类的分布式隐式事务的更多相关文章

  1. 基于 Transaction 类的分布式显式事务

    自.NET2.0以来增加了System.Transactions命名空间,为.NET应用程序带来了一个新的事务编程模型. 这个命名空间提供了几个依赖的TransactionXXX类.Transacti ...

  2. (4.19)sql server中的事务模式(隐式事务,显式事务,自动提交事务)

    (4.19)sql server中的事务模式(隐式事务,显式事务,自动提交事务) 1.概念:隐式事务,显式事务,自动提交事务 2.操作:如何设置事务模式 3.存储过程中的事务 XACT_ABORT 1 ...

  3. SQL Server显式事务与隐式事务

    事务是单个的工作单元.如果某一事务成功,则在该事务中进行的所有数据修改均会提交,成为数据库中的永久组成部分.如果事务遇到错误且必须取消或回滚,则所有数据库修改均被清除. SQL Server中有一下几 ...

  4. 1067: spark.components:NavigatorContent 类型值的隐式强制指令的目标是非相关类型 String

    1.错误描写叙述 此行的多个标记: -workId -1067: spark.components:NavigatorContent 类型值的隐式强制指令的目标是非相关类型 String. 2.错误原 ...

  5. SQLServer之创建隐式事务

    隐式事务创建注意事项 IMPLICIT_TRANSACTIONS为 ON 时,系统处于“隐式”事务模式. 这意味着如果 @@TRANCOUNT = 0,下列任一 Transact-SQL 语句都会开始 ...

  6. MYSQL中默认隐式事务及利用事务DML

    一:默认情况下,MySQL采用autocommit模式运行.这意味着,当您执行一个用于更新(修改)表的语句之后,MySQL立刻把更新存储到磁盘中.默认级别为不可重复读. 二:会造成隐式提交的语句以下语 ...

  7. C++ 隐式类类型转换和转换操作符

    隐式类类型转换 C++语言定义了内置类型之间的几个自动转换.也可以定义如何将其他类型的对象隐式转换为我们的类类型,或将我们的类类型的对象隐式转换为其他类型.为了定义到类类型的隐式转换,需要定义合适的构 ...

  8. 基于Selenium2+Java的UI自动化(8)- 显式等待和隐式等待

    一.隐式等待 package com.automation.waits; import java.util.concurrent.TimeUnit; import org.openqa.seleniu ...

  9. 读书笔记 effective c++ Item 41 理解隐式接口和编译期多态

    1. 显示接口和运行时多态 面向对象编程的世界围绕着显式接口和运行时多态.举个例子,考虑下面的类(无意义的类), class Widget { public: Widget(); virtual ~W ...

随机推荐

  1. Azure Web应用中设置静态虚拟目录的方法(比如部署Django需要用到)

    一.WEB应用中设置虚拟目录 二.在虚拟目录下放一个文件web.config,内容如下: <?xml version="1.0"?> <configuration ...

  2. scala 基础语法

    文章内容全部来自:http://twitter.github.io/scala_school/zh_cn/index.html 表达式 scala> 1 + 1 res0: Int = 2 值 ...

  3. Python2.7.14安装和pip配置安装及虚拟环境搭建

    目录 前言 1 Python2.7.14安装 2 pip配置安装 3 虚拟环境安装   前言 今天在搭建阿里云服务器,需要安装Python相关环境,之前在本机都已经安装过两遍,今天又来安装一遍,安装具 ...

  4. Java并发容器之非阻塞队列ConcurrentLinkedQueue

    参考资料:http://blog.csdn.net/chenchaofuck1/article/details/51660521 实现一个线程安全的队列有两种实现方式:一种是使用阻塞算法,阻塞队列就是 ...

  5. postgresql修改配置生效方法

    对于配置服务器,,太多时候我们在Linux中做的操作是,配置*.conf文件,然后重启服务.而很多服务都具有reload功能,而但是具体到某个配置,有时候直接说出需不需要重启服务而使得配置生效,这并不 ...

  6. C++ 函数返回局部变量的std::move()的适用场景(转)

    作者:神奇先生链接:https://www.zhihu.com/question/57048704/answer/151446405来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...

  7. 索引快速扫描(index fast full scan)

    一.索引快速扫描(index fast full scan) 索引快速全扫描(INDEX FAST FULL SCAN)和索引全扫描(INDEX  FULL SCAN)极为类似,它也适用于所有类型的B ...

  8. 源代码解析Android中View的layout布局过程

    Android中的Veiw从内存中到呈如今UI界面上须要依次经历三个阶段:量算 -> 布局 -> 画图,关于View的量算.布局.画图的整体机制可參见博文 < Android中Vie ...

  9. aapt 命令可应用于查看apk包名、主activity、版本等很多信息

    aapt即Android Asset Packaging Tool,在SDK的build-tools目录下,本文小结了一下该工具的用法. 配置环境变量后可直接在cmd使用该命令 http://blog ...

  10. Inno Setup入门(六)——在程序目录下创建文件夹

    创建文件夹可以使用[dirs]段实现,代码如下: [setup] ;全局设置,本段必须 AppName=Test AppVerName=TEST DefaultDirName="E:\TES ...