WCF分布式事务(EF)

WCF分布式事务(EF)

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

    才说分布式事务,首先,了解一下什么是交易。

 

事务有四个特性:ACID

    A是Atomicity,原子性。一个事务往往涉及到很多的子操作,原子性则保证这些子操作要么都做,要么都不做,而不至于出现事务的部分操作成功,而另外一部分操作没有成功。假设事务在运行的过程中错误发生,那么数据库将回滚到事务发生之前的状态。比方银行的转账服务。这个事务的终于结果一定是:某个账户的剩余金额添加了x,而另外一个账户的剩余金额降低了x,或者两个账户的剩余金额未发生变化。而不会出现其它情况。

 

    C是Consistency。一致性。一致性是指事务发生前后。都不会破坏数据库的约束关系,保证了数据库元素的正确性、有效性和完整性。

这样的约束关系能够是数据库内部的约束。比方数据库元素的值必须在一定的范围内,也能够是应用带来的约束,比方转账以后银行账户的剩余金额不能为负数。

 

    I是Isolation。隔离性。一个事务的操作在未提交曾经,是不会被并行发生的其它事务訪问到的。

也就是说。数据库操作不会看到某个事务的中间操作结果。比方转账过程中。用户是不能查询到一个账户剩余金额降低了,而另外一个账户剩余金额未发生变化的情况。

 

    D是Durability。持久性。事务完毕以后。它对数据库的影响是永久性的,即使在数据库系统发生宕机或者其它故障的情况下,这样的影响也会得到保持。

 

    简单的来说事务,事务是运行的最小单元。

 

比方运行的sql语句:delete from Table where FiledsA=’a’ 

    这一条sql语句就是一个 事务单元。即最小的运行颗粒。

 

假设运行两条sql语句:

    insert into Table values(‘1′,’zc’) 

    insert into Table values(‘1′,’zc’)— 与第一条主键冲突

 

    运行如上,包括两个运行单元。这两个运行单元所有运行成功。才算完毕任务,则这两个运行单元组成了一个新的事务。 

    正是由于有这样的情况出现,才引出了事务的概念。

 

 

对于上述的表述,两个运行单元都在同一个数据库server。即在 同一个数据库中操作两次。

 

那么,假设两个运行单元。分别在不同的数据库呢?

    比方说,跨行转账的样例。从银行A转账到银行B。这一个完整的操作,须要各自更改的数据库。

即。银行A中账户剩余金额降低,银行B中账户剩余金额添加。

 

    对于这样的不再同一个数据库server上的 操作。假设要把这两个运行单元。当成一个事务进行处理

则须要引入分布式事务的概念。

 

分布式事务:为了解决不同数据库server、分布式系统间的事务问题。

 

 

一下是一个实例,如今有两个服务:

    服务A:对数据库A进行增删改的操作

    服务B:对数据库B进行增删改的操作

 

如今主要说一下。WCF是怎样支持分布式事务的。

    WCF 集合了差点儿由.NET Framework 所提供的通信方法。

EF中的SaveChanges方法,封装了本地事务。

即:运行SaveChanges方法,才会将对实体的更改更新到数据库。

 

    既然要把WCF中的服务做成 支持分布式的形式。所以就要选择一个WCF的通信绑定协议。

这样client与服务端的通信才干够形成事务。

 

WCF中的绑定协议:

WCF分布式事务(EF)

当中WsHttpBinding协议,在MSDN上的解释:

WCF分布式事务(EF)

当然WCF中也能够使用<CustomeBinding>协议。这是一个自己定义的绑定协议。有兴趣的能够查一下。

 

分布式事务实现流程图:

 

没有分布式事务的情况下。如图:

WCF分布式事务(EF)

    带红框的是一个事务颗粒。可是依据业务要求。WcfService1WcfService2须要合并成一个事务。所以须要加上分布式事务。

 

使用分布式事务的情况,如图:

WCF分布式事务(EF)

 

分布式事务的配置:

 

服务端webconfig

<system.serviceModel>
    <bindings>
      <wsHttpBinding> <!--使用WsHttpbinding协议-->
        <!--启动事务流-->
        <binding name="WsHttpBinding_Default" transactionFlow="true" />
      </wsHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="Basic">
          <serviceMetadata httpGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <!--service的name是服务端的实现类-->
      <service name="BasicService.BasicService" behaviorConfiguration="Basic">
        <endpoint address ="" binding="wsHttpBinding" bindingConfiguration="WsHttpBinding_Default" contract="BasicContracts.IBasicService" /><!--contract是服务端的契约(接口)  命名空间+类名-->
      </service>
    </services>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" minFreeMemoryPercentageToActivateService="1" />  
  </system.serviceModel>

clientwebconfig

<system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="WsHttpBinding_Default"  transactionFlow="true" />
      </wsHttpBinding>
      
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment  multipleSiteBindingsEnabled="true" />

    <client>
      <!--考试服务终结点-->
      <endpoint address="http://192.168.24.146:8111/ExamService.svc?wsdl"
        binding="wsHttpBinding" bindingConfiguration="WsHttpBinding_Default"
        contract="ExamContracts.IExamService"
        name="WsHttpBinding_Services" />
      <!--基础服务终结点-->
      <endpoint address="http://192.168.24.146:8222/BasicService.svc?wsdl"
          binding="wsHttpBinding" bindingConfiguration="WsHttpBinding_Default"
          contract="BasicContracts.IBasicService"
          name="WsHttpBinding_Services" />
    </client>

  </system.serviceModel>

 

    以上是client与server端的配置文件。

    对于服务端的方法。假设要求 server端的某个方法。自己能够被其它的事务包括。则须要对这样的方法上面加上一个特性。

 

//契约类(接口)特性
[ServiceContract(SessionMode = SessionMode.Required)]
    public partial interface IBasic
    {
        [OperationContract]
        [TransactionFlow(TransactionFlowOption.Allowed)]
        void AddBasic(T_Student en);
    }

//实现类特性
public partial class BasicService:IBasic
    {
        [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]        
        public void AddBasic(T_Student en)
        {
            DBBasic dbContext = new DBBasic();

            T_Student enTemp = new T_Student();

            enTemp.StudentId = en.StudentId;
            enTemp.Sex = en.Sex;
            enTemp.College = en.College;
            enTemp.Age = en.Age;

            dbContext.T_Student.Add(enTemp);
            dbContext.SaveChanges(); //真正的保存到数据库 
        }
    }

 

在契约类上面的特性,TransactionFlowOption有多个属性能够选择。

 

    TransactionFlowAttribute 仅仅能用于服务方法(Operation/Method)上,它同意我们进行不同的事务參与设置。有一点要注意,我们不能为 IsOneWay=true 的服务设置事务支持。

 

    TransactionFlowOption.NotAllowed: 不參与不论什么事务。(默认值)

    TransactionFlowOption.Allowed: 同意參与事务。也就是说,假设调用方(client)和服务Binding启用了事务,则參与。

    TransactionFlowOption.Mandatory: 强制启用事务。调用方(client)和服务 Binding 必须启用事务才干调用本服务。

 

client,在组合 两个 事务的时候,须要:

 

	using (TransactionScope trans = new TransactionScope())
            {
                //获取考试服务
                IExam examService = ExamServiceFactory.GetExam();
                //获取基础服务
                IBasic basicService = BasicServiceFactory.GetStudent();

                //加入考试(正确)
                T_Exam enExam = new T_Exam();
                enExam.ExamId = "1";
                enExam.ExamRoom = "501";
                enExam.StudentId = "11040342031";
                examService.addExam(enExam);

                ////加入基础(正确)
                //T_Student enStudent = new T_Student();
                //enStudent.StudentId = "11040342031";
                //enStudent.Age = "22";
                //enStudent.College = "师范学院";
                //enStudent.Sex = "男";
                //basicService.AddBasic(enStudent);

                //提交
                trans.Complete();
            }

这两个 分别具有事务性质的颗粒,通过以上就能够组合成一个新的事务。

 

 

    使用Wshttpbinding通讯方式之后,WCF中的方法 就能够被其它的事务包进去。

    事务,就是由一个个小颗粒组成。事务,也能够由若干个事务组成。

    分布式事务。也就是整合一些分别在不同机器上的事务。除了给其它服务提供的事务 加个 特性之外。其它的也都和传统事务同样了。

    Demo下载链接:http://download.csdn.net/detail/zc474235918/8505775

         

 

版权声明:本文博客原创文章。博客,未经同意,不得转载。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/117423.html原文链接:https://javaforall.net

(0)
上一篇 2022年1月6日 上午6:00
下一篇 2022年1月6日 上午6:00


相关推荐

  • clion2021 激活码(最新序列号破解)

    clion2021 激活码(最新序列号破解),https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月18日
    171
  • linux dstat,使用Dstat来进行Linux综合性能诊断

    linux dstat,使用Dstat来进行Linux综合性能诊断性能测试、评估和优化一直是系统管理维护人员工作的重点。当我们针对一台生产应用进行分析的时候,获取如CPU、内存、IO、网络吞吐和进程负载的基础数据,对于后续的性能评测和优化是至关重要的。Linux作为目前应用最广泛的服务器操作系统,为了应对各种性能问题,已经发展出很多原生的性能检测工具。从top、vmstat、iostat到mpstat,已经可以对操作系统主要性能方面进行详细的分析。面对越来越复杂…

    2022年6月24日
    23
  • RenderControl获取控件输出的HTML

    RenderControl获取控件输出的HTML之前写过一篇文章,通过实现ICallbackEventHandler接口,实现其两个方法。RaiseCallbackEvent实现回调处理,GetCallbackResult实现将处理产生的结果输出到客户端。为了实现页面不刷新,我们在GetCallbackResult方法中可以将前台的控件html通过RenderControl方法获取,并Return到客户端…

    2022年7月20日
    20
  • 国内不用备案的cdn_2018年广电总局电影备案查询

    国内不用备案的cdn_2018年广电总局电影备案查询随着行业老大哥百度云加速的CDN关闭,不,不能说是关闭,是不再面向国外用户(实则是不再面向未备案中国用户),喜欢简单而快捷方式的草根大佬们不知道该何去何从,特别是用习惯了CDN的大佬,更是讨厌裸奔的感觉,没了层CDN,还真就觉得不安全了!事实上,CDN确实让我们的网站加速了不少,当然,排除那些劣质的CDN,有人可能会感觉不用CDN自己的网站反而会快很多,这个是错误的认知,你的网站访问不大的…

    2025年10月21日
    3
  • 【AI智能体】Coze 搭建个人旅游规划助手实战详解

    【AI智能体】Coze 搭建个人旅游规划助手实战详解

    2026年3月13日
    2
  • modprobe 命令

    modprobe 命令1 命令介绍编辑简介 Linux 命令 modprobe 功能说明 自动处理可载入模块 语 法 modprobe acdlrtvV help 模块文件 符号名称 符号值 补充说明 modprobe 可载入指定的个别模块 或是载入一组相依的模块 modprobe 会根据 depmod 所产生的相依关系 决定要载入哪些模块 若在载入过程中发生错误 在 modprobe 会卸载

    2026年3月19日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号