本地事务和分布式事务工作实践

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了本地事务和分布式事务工作实践 相关的知识,希望对你有一定的参考价值。

  • 一:从事务的历史说起

      知已知彼,百战不败。想了解事务,我们从事务的历史说起。

      在Windows平台上,事务的概念最开始出现在关系型数据库中,但是随着.net平台的发展,事务包括的的范围也越来越宽,先一睹为快,

      在关系型数据库中的事务是通过begin transaction,rollback transaction, commit 等关键字来实现事务的。

    BEGIN TRANSACTION  UPDATE [dbo].[T_ACCOUNT] SET BALANCE = BALANCE + @amount WHERE ID = @toAccount  IF @@ERROR <> 0   BEGIN 
        ROLLBACK TRANSACTION  END ELSE
        COMMIT TRANSACTION

      随着面象对象的发展,.net的诞生,在.net 1.* 的版本中,可以通过ADO.NET来实现数据库的事务。把事务交给业务程序来控制,使业务程序的本职发挥的淋漓尽致,而从数据库的角度来看,数据库也能更专一的进行数据的存储。达到了各尽其责的效果。

    using (DbTransaction transaction = connection.BeginTransaction())
     {
        command.Transaction = transaction;     try
        {
            command.ExecuteNonQuery();
            transaction.Commit();
        }    catch (Exception ex)
        {
            transaction.Rollback();        throw new Exception(ex.Message);
        }
    }

      万物是发展的,程序的发展也是永无止境的。某天有一个需求:创建一个客户信息,其中包括姓名和头像。姓名保存在数据库,头像保存在服务器的硬盘中。姓名和头像的保存有一个失败都是一个不完整的操作,都要回滚到初始状态。用ADO.NET的事务显示不能实现这个要求。因为回滚资源包括了数据库硬盘。基于这种情况,.net 2.0推出了System.Transactions事务。

    using (TransactionScope transactionScope = new TransactionScope())
    {
        bankService.Pay("111", 50);
        bankService.Receipt("222", 50);
         transactionScope.Complete();
    }

      System.Transactions名称空间下的事务,是.net的主推事务。

    二:事务有关概念

      第一节,我们都用代码把事务实践了一把,那还有必要来说事务的概念和事务在运行过程中涉及到的对象呢?如果你想深入了解事务,这一步是必须的。

         事务的定义和属性:

      1,什么是事务:它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。

      2,事务特性:接触事务,都是从事务的ACID开始,原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。每个特性的定义僵硬,枯燥,不易理解,读了好几篇都有让人想跳楼的欲望。今儿换一个方式来说事务特性。

      银行转款是事务的经典示例,可能因为钱与银行扯的上关系,一提到银行,大家都精神倍爽,为了不另类,所以我也决定用银行转款来说事务的四大特性。

      2.1:原子性:银行转款分为"转出"和"接收"两步,比如给异地结婚的朋友送礼金,自己的钱已经转出去了,但是朋友没有收到礼金,这时大家都心急如焚。所以转款必须要保证"转出"和"接收"要么都成功,要么都不成功。这就是转款的原子性。

      2.2:一致性:给朋友转款888元RMB作为婚礼的礼金,但是朋友只收到777元RMB。这时你不爽了,你朋友也不爽,所以转款要必须保证数据的一致性。

      2.3:隔离性:转款分为"转出"和"接收"两步,理论上是可以同时进行的,但是在实际生活中确有时间差,即使相差0.0001秒,在这段时间里,自己的账户和朋友的账户都不能进行查询操作,即使查询了,也是处于一种等待状态。在这期间外界无法对数据进行查询访问,所以称之为隔离性。

      2.4:持久性:转款这个操作被银行记录起来,过很多年后,你都还能查询到转款这个记录。这就是持久性。

       事务涉及的对象:

      1,资源:应用程序存储和获取数据的地方,可以是数据库,文件,也可以是内存。如果是应用程序的事务块代码中涉及到的数据库,文件,内存,那这些资源就称为事务型资源

      2,资源管理器:在事务模型中,应用不是直接访问资源,而是通过中间介访问资源,这个中间介就叫资源管理器。资源分为可持久化资源(对应了持久化资源管理),易失资源(对应了易失资源管理器)。

      3,事务管理器:实现事务的开始,提交,回滚。

      事务提升:

      要认识事务提升,必须要弄清楚事务管理器的类型。如下作了非常详细的介绍:

      1:轻量级事务管理器:作用于开启事务的应用程序域,只能包含一个持久化资源,如果再添加一个持久化资源,将被轻量级事务管理器忽略。但是可以登记多个易失资源。目前轻量级事务管理器只支持SQL 2005以及SQL2005以上的版本持久化资源。

      3:内核事务管理器:在Vista被引入,并后续于Windows Server 2008,WIN7。引入内核事务管理器主要是把文件管理(NTFS文件系统)和注册表管理纳入事务范畴。我们将那些支持事务的文件系统和注册表叫作事务型文件系统(TxF)和事务型注册表(TxR)。 之所以称为内核事务管理器,是因它运行在内核模式上,而不是在用户模式上。同样内核事务管理器只支持一个持久化资源。

      3:分布式事务协调器:每一台电脑上只有一个分布式事务协调器,它管理了当前计算机的所有事务资源。它可以跨程序域,跨进程,跨机器,跨网络来执行事务。当事务跨机器时,每台机器的分布式事务协调器按照相应的协议工作,实现对整个事务的管理,它对应的事务管理协议有Ole-Tx和WS-Atomic Transaction(WS-AT)这些。 分布式事务协调器能够管理一个分布式事务涉及的所有事务型资源,不管具体的事务型资源分布在何处。

      事务提升:事务是一个动态执行的操作序列,在整个过程中,不可能预知资源的登记情况。所以轻量级事务管理器作为默认的事务管理器,随着事务的逐步执行,如果涉及到内核事务资源,那么将提升为内核事务管理器。如果出现对多个事务资源的访问,或者当前事务涉及跨域(调用另外一个服务),就会提升为分布式事务协调器。Windows采用事务提升机制进行事务管理器的选择。

      技术分享

    三:事务的分类

      1:本地事务

      轻量级事务管理器,内核事务管理器都只支持本地事务。本地事务相对简单,这儿不作重点简述。

      2:分布式事务

      理解分布式事务是怎样实现的,事务提交树是关键。

      事务提交树:事务提交树的根是事务初始化服务所在的机器的DTC,它在整个事务提交过程中充当着总协调者,又被称为全局提交协调器。资源管理器充当着事务提交树的叶子节点,它们的父结点为本机的DTC,分布于不同机器的DTC按照事务的传播路径形成了上下级关系。

      技术分享

      在一个分布式事务中,事务的初始化和提交是属于一个对象,只有最初开始的事务才能被提交,我们将这种能被初始化和提交的事务称作可提交事务。随着参与者逐个登记到事务中,它们本地的事务实际上依赖着这个最初开始的事务,所以我们称这种事务叫依赖事务。

    四:示例

  • 我们如果是仔细阅读这篇文章不难发现他提供了一个.exe类型文件的下载。先把这个TxF2007_07.exe文件下载到本地硬盘,执行它,可以得到一个关于 c#的 KtmIntegration.csproj 的项目,我们用visual studio来打开这个项目,并且重新重成这个项目,可以得到一个KtmIntegration.dll文件。在你要实现的文件事务的项目中引入这个.dll文件,那你就可以很顺利的实现文件事务的操作了。具体代码:

    using System;using System.IO;using System.Transactions;using Microsoft.KtmIntegration;namespace Exercise.WebLocalTransaction
    {    public partial class Test02 : System.Web.UI.Page
        {        protected void Page_Load(object sender, EventArgs e)
            {            using (TransactionScope transactionScope = new TransactionScope())
                {                try
                    {
                        FileStream stream = TransactedFile.Open(                        @"D:/Sam Xiao.txt"
                            , FileMode.OpenOrCreate
                            , FileAccess.ReadWrite
                            , FileShare.ReadWrite);
                        StreamWriter writer = new StreamWriter(stream);
                        writer.WriteLine(String.Concat("执行一个事务代码:",DateTime.Now.ToString(),Environment.NewLine));
                        writer.Close();                    //int x = 0;                    //int y = 10;                    //int z = y / x;                    transactionScope.Complete();
                    }                catch
                    {
    
                    }
                }
            }
        }
    }

    不要忘记了引入using Microsoft.KtmIntegration;名称空间。在段代码没有异常的情况下,我们可以看到D盘里顺利创建了一个关于Sam Xiao.txt的文件。我们故意在这段代码中抛出一个被0整除的异常,那么整个操作就会回滚。

      分布式事务

      在.net平台上,主要是通过WCF的手段来实现程序的分布式开发。在WCF事务体系:主要解决了事务在服务中的流转,以及解决服务内部直接或间接访问事务型资源的协作。

      用WCF来演示事务的时候,要选择好WCF的绑定类型,有一部份绑定是不支持WCF的事务传播的。我们选择wsHttpBinding 来做WCF的事务演示。

      1,首先定义好WCF的服务契约

    [ServiceContract(Name = "IBankingService")]public interface IBankingService
    {
          
        [TransactionFlow(TransactionFlowOption.Mandatory)]
        [OperationContract(Name = "Transfer")]    void Transfer(string fromAccountId, string toAccountId, double amount);
    
        [TransactionFlow(TransactionFlowOption.Mandatory)]
        [OperationContract(Name = "Pay")]    bool Pay(String accountID, double amount);
    
        [TransactionFlow(TransactionFlowOption.Mandatory)]
        [OperationContract(Name = "Receipt")]    bool Receipt(String accountID, double amount);
    }

      2,实现WCF的服务

    [ServiceBehavior(TransactionIsolationLevel = System.Transactions.IsolationLevel.Serializable)]public class BankingService : IBankingService
    {
        [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]    public void Transfer(string fromAccountId, string toAccountId, double amount)
        {        throw new NotImplementedException();
        }
    
        [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]    public bool Pay(string accountID, double amount)
        {        throw new NotImplementedException();
        }
    
        [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]    public bool Receipt(string accountID, double amount)
        {        throw new NotImplementedException();
        }
    }

      3,WCF宿主配置

    <system.serviceModel>
          <behaviors>
              <serviceBehaviors>
                  <behavior name="sBehaviorConfig">
                      <serviceMetadata httpGetEnabled="true" />
                      <serviceDebug includeExceptionDetailInFaults="true" />
                  </behavior>
              </serviceBehaviors>
          </behaviors>
    
          <bindings>
            <wsHttpBinding>
              <binding name="wshttpConfig" transactionFlow="true" >
                <security mode="None" />
              </binding>
            </wsHttpBinding>
          </bindings>
          
          <services>
            <service name="Exercise.Service.BankingService" behaviorConfiguration="sBehaviorConfig">
              <endpoint address="mex"  binding="wsHttpBinding" bindingConfiguration="wshttpConfig" contract="Exercise.Contract.IBankingService"></endpoint>
            </service>
          </services>
          <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
        </system.serviceModel>

      4,WCF客户端配置

    <system.serviceModel>
        <bindings>
          <wsHttpBinding>
            <binding name="WSHttpBinding_IBankingService" transactionFlow="true">
              <security mode="None" />
            </binding>
          </wsHttpBinding>
        </bindings>
        <client>
          <endpoint address="http://localhost:9100/BankingService.svc/mex"
              binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IBankingService"
              contract="Exercise.Contract.IBankingService" name="WSHttpBinding_IBankingService" />
        </client>
      </system.serviceModel>

      5,调用服务

    IBankingService bankService = WcfProxy.CreateProxy<IBankingService>("WSHttpBinding_IBankingService");protected void Page_Load(object sender, EventArgs e)
    {    using (TransactionScope transactionScope = new TransactionScope())
        {
            bankService.Pay("111", 50);
            bankService.Receipt("222", 50);
            transactionScope.Complete();
        }
    }
  • 项目Maven构建,真实大型互联网架构,做到高并发,大数据处理,整个项目使用定制化服务思想,提供模块化、服务化、原子化的方案,将功能模块进行拆分,可以公用到所有的项目中。架构采用分布式部署架构,所有模块进行拆分,使项目做到绝对解耦,稳定压倒一切~~

    持续集成:

    1. 我的待办工作流服务(提供Webservice服务)

    2. 我的待办工作流集成JMS消息服务(支持高并发,可支持成千上万系统集成)

    3. 我的任务提供Rest服务,完成日常的工作管理,通过定时调度平台,动态生成我的任务、循环周期任务、定时邮催提醒完成任务等

    4. 文件上传、多线程下载服务化、发送邮件、短信服务化、部门信息服务化、产品信息服务化、信息发布服务化、我的订阅服务化、我的任务服务化、公共链接、我的收藏服务化等

    系统模块:

     1.  用户管理:

          用户信息管理(添加、删除、修改、用户授权、用户栏目管理、查询等)

          用户组管理(添加、删除、修改、用户组栏目授权,栏目授权、查询、用户组人员添加查询等)

          用户角色管理(添加、删除、修改、用户角色授权、用户角色栏目信息查询设置等)
     2.  文章管理:

          栏目管理:查询无限极栏目树、创建无限极栏目树分类(导航栏目、图片列表栏目、文章列表栏目、文章内容栏目等)、删除、修改栏目信息。

          文章管理:创建、删除、修改文章,多维度文章查询,包括已发布、未发布、所有文章等。文章富文本编辑器、文章多文件上传、文章状态控制等。
    3.  系统设置:

           数据字典管理:支持中、英文信息,支持无限级别分类配置,动态控制是否可用等。

           部门信息管理:支持中、英文无限级别部门信息增加,删除,修改操作,部门列表、树心查询等。

           日志管理:系统日志列表查询、在线查看、在线下载等

           路线管理:集成百度地图API,提供线路查询管理功能

           Druid Monitor(监控):集成阿里巴巴连接池,提供在线连接池监控程序,包括:数据源、SQL监控、URL监控、Session监控、Spring监控等

           网站信息管理:通过系统配置文件进行网站内容操作,包括邮件服务器配置、公司基本信息配置等。

     4.  集成REST服务,可以用作独立服务平台(提供大量实例及测试平台,包括:文件上传下载、邮件短信发送、部门、产品、公共连接、我的收藏、我的任务、信息发布等)

     5.  集成Quartz调度可以用作定时调度平台(动态配置调度类、调度时间,使程序自动执行某些业务)

     6.  Lucene搜索引擎可以将文件资料索引化,支持文件内容搜索、关键字搜索、高亮关键字等,使信息在毫秒内提取查询出来

     7.  用户设置功能包括修改用户信息,修改密码、发送消息,修改个人图片,查看角色、查看用户组,管理员修改角色、用户、用户组等。

     8.  集成Webservice平台包括jaxws服务、CXF框架,配置双加密的权限认证。使服务集成更加安全。

     9.  Bootstrap html5提供了两套前台开环境包括CMS和电子商务网站,使您的开发更加的简洁。

    技术点:

    1.  Springmvc + Mybatis集成、SpringSecurity权限控制、Spring AOP事务处理。

    2.   Wink Rest服务、Webservice服务:jaxws、CXF等

    3.  IO 流上传下载文件,多线程操作

    4.  发送邮件,配置邮件服务器,发基于html、纯文本格式的邮件

    5.  MD5加密 (登陆密码校验加密等),用户统一Session、Cookie管理,统一验证码校验等。

    6.  数据库连接池统一配置 

    7.  Quartz定时调度任务集成(直接通过配置即可)

    8.  Httpclient破解验证码,登陆联通充值平台

    9.  汉字、英文拆分、可以用作文档关键字搜索等。

    10.  Base64图片处理,支持PC,androidios

    11.  Service Socket 、Client Socket 通信技术(已经做过GPRS数据获取,并用到了项目中)

    12.  提供大量工具类,可以直接使用

    13.  Maven项目构建,您可以直接做架构,可以提升自己的学习能力,使您成为真正的架构师。


    技术分享

     

    技术分享

    技术分享

     

    技术分享

     

    技术分享

     

    技术分享

     

    技术分享

     

    技术分享

     技术分享
     

    技术分享

     

    技术分享

     

    技术分享

     

    技术分享

     

    技术分享技术分享
     

     

    技术分享技术分享
     

     技术分享
     

    技术分享技术分享

     技术分享

     技术分享

  1. 2. 提供高并发JMS消息处理机制
    3. 所有功能模块化、所有模块服务化、所有服务原子化的方式,提供可拓展的服务模型,使程序稳定运行,永不宕机
    4. 提供Wink RestWebservice服务,故可作为独立服务平台部署

    框架整合:

    Springmvc + Mybatis + Shiro(权限) + REST(服务) + WebService(服务) + JMS(消息) + Lucene(搜搜引擎) + Quartz(定时调度) + Bootstrap Html5(支持PC、IOS、Android)

    框架简介:

  1. 1. 使用阿里巴巴Druid连接池(高效、功能强大、可扩展性好的数据库连接池、监控数据库访问性能、支持Common-Logging、Log4j和JdkLog,监控数据库访问)


以上是关于本地事务和分布式事务工作实践 的主要内容,如果未能解决你的问题,请参考以下文章

分布式技术专题「架构实践于案例分析」总结和盘点目前常用分布式事务特别及问题分析(中)

分布式技术专题「架构实践于案例分析」总结和盘点目前常用分布式事务特别及问题分析(中)

分布式事务设计与实践-TCC与Saga

分布式事务-1 存储层(DB)解决方案

分布式事务原理与实践

谈谈对分布式事务的一点理解和解决方案