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. 百度搜索URL参数

    http://www.baidu.com/s?wd=关键字wd(Keyword):查询的关键词:http://www.baidu.com/s?wd=关键字&cl=3cl(Class):搜索类型 ...

  2. 更新image的方法

    1. 修改container 1.1 执行 docker images 查看目前的所有images: REPOSITORY       TAG                 IMAGE ID     ...

  3. Linux中查看系统版本的方法

    一.Linux系统中,XShell连接进去之后,查看系统版本的方法如下: 1.查找release文件 find /etc/ -name *-release 例如: 或者 2.查看release文件 c ...

  4. TaskFactory设置并发量

    Task对象很多人知道了(使用Task代替ThreadPool和Thread, C#线程篇—Task(任务)和线程池不得不说的秘密(5)) 相对的还有TaskScheduler 这个调度器,可以自定义 ...

  5. C++ 第十一课 标准c内存函数

    calloc() 分配一个二维储存空间 free() 释放已分配空间 malloc() 分配空间 realloc() 改变已分配空间的大小 calloc 语法:     #include <st ...

  6. JAVA GC优化入门

    为什么需要优化GC? JAVA的GC是面试必考的题目,可是在实际项目中什么时候使用GC哪?或者应该什么时候优化GC哪?有句名言:“GC优化永远是最后一项任务”. 在使用GC之前,应该考虑一下进行GC的 ...

  7. HttpLuaModule——翻译(Nginx API for Lua)

    现在我已经将翻译的内容放到:http://wiki.nginx.org/HttpLuaModuleZh Nginx API for Lua Introduction 各种各样的*_by_lua和*_b ...

  8. python PDF报表服务

    先看牛逼的草图 知乎上刚看到类似的需求 Python Web导出有排版要求的PDF文件 关键技术

  9. 〖Linux〗gun screen 配置文件

    screen 默认使用 bash shell,一般情况下screen只用于android build,tmux则是我的日常使用多终端管理工具. # Default Shell shell " ...

  10. APache PDFbox API使用(1)----简单介绍

    因为项目的须要.近期在学习APache  PDFbox API,Apache PDFbox API是Apache Java 开源社区中个一个项目,其受Apache 版权 V2的保护,其提供了以下的功能 ...