专栏首页angularejs学习篇关于分布式事务的实现梳理

关于分布式事务的实现梳理

关于分布式事务的实现梳理

场景描述

   在实际开发过程中,往往会遇到微服务架构中(数据分区存储),用户的一个操作,会设计到多个模块的数据落地或者更新查找,并且每个模块数据都是存储在不同的数据库,并且业务要求还需要确保操作结果的一致性。比如,用户在下单时:首选需要落地订单数据,其次,需要落地:账单数据、日志数据、或者库存更新等等操作。首先我们想到的解决方式就是事务来实现,由于在不同库,所以需要涉及到分布式事务。

解决方案

   为了达到上述要求,在实现上根据我的经验大概有如下3种实现方式:

  其一、分布式事务

    分布式事务就是采用微软提高的分布式事务机制实现,在实现效率上不是很理想,并且也不是符合微服务设计的单一功能原则,所以不是很建议使用。

  其二、消息队列

    消息队列是现在使用的比较多的解决方案,通过一些消息队列中间件, 实现逻辑解耦,异步实现,响应效率也大大提升。

  其三、异步作业

    异步作业的实现思路和消息队列类似,都是对操作的步骤的解耦,异步实现,但是在处理上有一定的延迟性,因为异步作业是周期性的执行,但是异步作业也是对消息队里的一个保障和补充。

    在实际使用过程中,一般都是消息队列和异步作业配套实现,当消息队列出现问题,异步作业能正常的把流程走完。

  分布式事务

   在介绍分布式事务时,分两部分来介绍:sql分布式事务、ADO.NET分布式事务。

  sql分布式事务

  分布式事务的实现,首先总结一下sql分布式事务的实现,主要适用于存储过程或者方法函数中。

   sql分布式事务的关键词为:distributed,分布式事务在使用前,需要做一下几点的环境准备:

分布式事务需要的前期环境准备:

  在控制面板--->管理工具--->服务 中,开启Distributed Transaction Coordinator 服务。

  a、控制面板->管理工具->组件服务->计算机->我的电脑->右键->属性   b、选择MSDTC页, 确认"使用本地协调器"   c、点击下方"安全配置"按钮   d、勾选: "允许网络DTC访问","允许远程客户端","允许入站","允许出站","不要求进行身份验证".

  e、对于数据库服务器端, 可选择"要求对呼叫方验证"   f、勾选:"启用事务Internet协议(TIP)事务"。   g、在双方防火墙中增加MSDTC.exe例外   可用命令行: netsh firewall set allowedprogram %windir%/system32/msdtc.exe MSDTC enable

sql分布式事务的使用实例:

use ecshop;
go

set XACT_ABORT ON

--开启分布式事务
begin distributed tran tranInsetName

begin

----需要执行的sql语句;
    insert into ecshop..TEST_name values(8,8)
    insert into ecshopTest..TEST_name values(9,null)
    insert into ecshopTest..TEST_name values(8,8)
commit tran tranInsetName
end
go

  ADO.NET中分布式事务

下面在总结一下ADO.NET中分布式事务的使用:

    ADO.NET分布式事务关键词为:TransactionScope

    ADO.NET分布式事务需要引用命名空间:using System.Transactions

首先需要了解ADO.NET分布式事务的级别

    Chaos:无法改写隔离级别更高的事务中的挂起的更改。

    ReadCommitted:不可以在事务期间读取可变数据,但是可以修改它。

    ReadUncommitted:可以在事务期间读取和修改可变数据。

    RepeatableRead:可以在事务期间读取可变数据,但是不可以修改。可以在事务期间添加新数据。

    Serializable:可以在事务期间读取可变数据,但是不可以修改,也不可以添加任何新数据---默认级别。

    Snapshot:可以读取可变数据。在事务修改数据之前,它验证在它最初读取数据之后另一个事务是否更改过这些数据。如果数据已被更新,则会引发错误。这样使事务可获取先前提交的数据值。

    Unspecified:正在使用与指定隔离级别不同的隔离级别,但是无法确定该级别。如果设置了此值,则会引发异常。

    实例代码:

       //// 事务附件消息
            TransactionOptions transactionOption = new TransactionOptions();
            //设置事务隔离级别
            transactionOption.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
            // 设置事务超时时间为60秒
            transactionOption.Timeout = new TimeSpan(0, 0, 60);

            //启动一个分布式事务
            using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, transactionOption))
            {
                ///// 处理一个库操作
                using (SqlConnection conn = new SqlConnection(sqlConn))
                {
                    conn.Open();
                    using (SqlCommand cmd = conn.CreateCommand())
                    {

                        cmd.CommandText = "insert into TEST_name values(25,25);insert into TEST_name values(26,null);";
                        cmd.ExecuteNonQuery();
                        cmd.CommandText = "insert into TEST_name values(26,null);";
                        cmd.ExecuteNonQuery();
                    }
                }

                ///// 创建一个新的连接,处理另外一个库操作
                using (SqlConnection conn = new SqlConnection(sqlConn))
                {
                    conn.Open();
                    using (SqlCommand cmd = conn.CreateCommand())
                    {

                        cmd.CommandText = "insert into TEST_name values(25,25);insert into TEST_name values(26,null);";
                        cmd.ExecuteNonQuery();
                        cmd.CommandText = "insert into TEST_name values(26,null);";
                        cmd.ExecuteNonQuery();
                    }
                }
            }

分布式事务在执行效率上低,在实际项目中不怎么使用,尤其是微服务项目。在微服务项目中,主要通过消息队列变相的实现事务,确保操作结果的一致性

  消息队列

   消息队列在实际工作中使用场景还是很多的,主要目的是实现步骤解耦、消峰、高并发。在这只简单整理一下消息队列在分布式事务中的使用,

  消息队列在分布式事务中使用逻辑大概是:主流程生成完成后,生成一个消息,直接返回结果给用户,通过消息中间件,告诉后续流程的消费者,进行各自的后续流程逻辑处理、

  比如:以一个实际的电商中用户订单支付成功为例,假设订单支付成功后首先需要更新订单状态,其它后续流程包括:落地账单数据、落地分佣数据,假设账单数据和分佣数据没有数据关系,可并行执行

  那么实现逻辑是:

    消息生产者:支付成功,更新订单状态-->发送一个消息到消息队列中间件(广播)

    消息消费者:此处有两个消息消费订阅对象,账单落地、分佣数据落地。两个消息消费者都会收到一条消息,并做各自的数据落地处理

消息队里,在系统架构上,或者用户体验上都有是一个很不错的选择,但是在实际工作中,仅仅使用消息队里也不是完成的解决方案,因为消息队列也有肯能出现宕机或者数据丢失,导致业务逻辑中断,所以在实际工作中,一般还会借助一个辅助程序(异步作业),实现对消息队里的补充的加固

  异步作业

   异步作业的实现思路就是,程序定期的执行某一些数据流程操作,比如:账单数据落地异步作业小程序,查找到订单支付成功,但是账单为成功,则落地账单数据

  在实现上,推荐使用:Quartz开源的异步作业框架,使用起来很不错。

  异步作业的宿主有:控制台程序、窗体程序、IIS、Windows服务

  在实际开发过程中,推荐使用windows服务,方便控制管理

总结

   上面对分布式事务做了简单的介绍,如果有说的不对的地方勿喷,望多多指点学习。

  通过上面的介绍,我们也知道在实际项目中的使用选择,我还是建议采用:消息队列+异步作业 来确保系统的高可用性

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • sql事务的使用及其技巧整理

      在实际项目开发中,为了确保数据操作结果的一致性等要求,事务是一个必不可少的解决利器。

    小小许
  • JQuery中的动画

      这两种方法是jQuery动画的最基本方法。当为元素调用show方法时相当于将该元素的display样式改为block或者inline,同理,如果当元素调用h...

    小小许
  • 瀑布流AJAX无刷新加载数据列表--当页面滚动到Id时再继续加载数据

    瀑布流加载显示数据,在当下已经用的很普遍,尤其是我们在做网上商城时,在产品列表页面已经被普遍使用。

    小小许
  • 突破Java面试(44)-分布式事务解决方案

    只要聊到做了分布式系统,必问分布式事务,若你对分布式事务一无所知的话,确实很坑,起码得知道有哪些方案,一般怎么来做,每个方案的优缺点是什么。

    JavaEdge
  • 内网渗透的一些工具和平台

    渗透测试平台类: Metasploit,这个大家都不陌生了,集信息收集,预渗透,渗透,后渗透,木马,社会工程学于一体的平台,居家旅行,杀人越货之必备。SE...

    奶糖味的代言
  • 内网渗透的一些工具和平台汇总

    各位老司机在日常的渗透过程中,都会有自己趁手的工具集合,有开源的有私有的,不管什么样的工具组合,能够达到最佳的渗透效果就是好工具,老司机分享一点自己在内网渗透中...

    HACK学习
  • Linux下双网卡Firewalld的配置流程

    实验室拟态存储的项目需要通过LVS-NAT模式通过LVS服务器来区隔内外网的服务,所以安全防护的重心则落在了LVS服务器之上。笔者最终选择通过firewalld...

    HappenLee
  • MYSQL group by 怎么能快一点,之别一根筋

    一般来都有这样一个说法,MYSQL 表的数据超过500万行就不行了,而在这个说法之后就是MYSQL 的group by 的性能奇差无比。

    AustinDatabases
  • Java Web技术经验总结(十一)

    阿杜
  • 最新Github上各DL框架Star数量大PK | 附各框架性能对比分析

    用户1737318

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动