Alwayson是微软从SQL2012开始引入的一种高可用和高性能架构,它既可以实现故障转移,同时又能实现查询分离,是当前SQL server的所有架构中最优秀的一种。

因此,一般我们都会推荐使用AlwaysON来部署生产数据库,不过,尽管AlwaysON的优势非常明显,但并非适应于所有的业务场景。

AlwaysON不支持分布式事务和跨数据库事务

什么是分布式事务和跨数据库事务

分布式事务是指通过分布式事务协调器(MSDTC)的统一控制、将事务中的每个操作分解到多台主机上分别执行、每台主机执行成功后整个事务才能提交的事务,分布式事务协调器用来保证数据的一致性。跨数据库事务与此类似,只是不会用到MSDTC,而是将DBID最小的一个作为分布式事务协调器。

为什么AlwaysON不支持分布式事务

如果在一个分布式事务执行期间AlwaysON发生了故障转移,AG服务从主副本转移到了辅助副本,分布式事务协调器因为收不到原主副本的事务提交确认信息,认为事务执行失败,然后将其他参与(分布式事务的)节点上的应要提交的事务回滚。对于新的主副本,因为没有参与之前的分布式事务,因此无法从分布式事务协调器获取事务的状态,继续维持现有的数据不变化,从而导致新副本与参与分布式事务的其他节点上的数据不一致。

备注:跨数据库事务的原因与此类似。

下面我们通过图例来展示这个过程:

下图:假设有ABC三个节点,AC之间做了AlwaysON,其中A.table1中a的初始值为0,B.table1中a的初始值为1000。有一个分布式事务1,需要将节点A的表中a加上1000,同时需要在节点B的表中a减去1000。

BEGIN TRAN 

Update A.table1 set a=a+1000 ; 

Update B.table1 set a=a-1000 ; 

COMMIT TRAN

正常情况下,最后的结果应该是A.table1.a=1000,B.table1.a=0,,C.table1.a=1000。

现在有这样一个场景,A和B都已经commit,A.table1.a=1000,B.table1.a=0,且A已经将事务1的操作通过日志同步到了主机C,C.table1.a=1000。

正常情况下,主机A和B都向事务协调器发送commit ack(提交确认)信息,事务协调器收到两者的确认信息后就可以将整个事务标记为提交。但现在A在发送commit ack信息时发生了宕机,分布式事务协调器只收到了主机B的commit ack,于是协调器将整个事务标记为失败,然后在主机B上回滚事务1的操作,此时B.table1.a=1000。

节点C虽然接管了AlwaysON集群,因为它并不是分布式事务的执行者之一,所以它无法从分布式事务协调器获取事务1的状态,因此它不会回滚,a的值保持不变。最后C.table1.a=1000、B.table1.a=1000,发生了数据不一致的问题。

参考文章:

http://blogs.msdn.com/b/alwaysonpro/archive/2014/01/06/not-supported-ags-with-dtc-cross-database-transactions.aspx;

https://msdn.microsoft.com/en-us/library/ms366279(v=sql.110).aspx;

AlwaysON的主副本使用传统的SQL Server故障转移集群

从上文可以看到,AlwaysON不支持分布式事务(和跨数据库事务)的根本原因在于主副本故障转移到辅助副本时会造成分布式事务执行不一致。

解决这个问题的焦点就是主副本和辅助副本的故障转移。如果主副本与辅助副本之间不允许故障转移(也就是处于异步同步模式下),辅助副本的职责只是接受来自主副本的日志,然后执行redo实现同步,这样一来就不会产生异常数据。

不过,主、辅副本无法故障转移后,主副本存在单点故障的风险,为了避免此类情况发生,我们可以为主副本建立传统的SQL Server故障转移集群。在这种架构下,如果主节点在执行分布式事务发生了故障转移,辅节点接管的SQL实例是原主节点的同一个实例,而且数据文件和日志文件是相同的,所以不会与其他参与分布式事务的节点产生数据不一致的问题。

alwaysOn为什么不支持分布式事务的更多相关文章

  1. spring boot + druid + mybatis + atomikos 多数据源配置 并支持分布式事务

    文章目录 一.综述 1.1 项目说明 1.2 项目结构 二.配置多数据源并支持分布式事务 2.1 导入基本依赖 2.2 在yml中配置多数据源信息 2.3 进行多数据源的配置 三.整合结果测试 3.1 ...

  2. 第三代微服务架构:基于 Go 的博客微服务实战案例,支持分布式事务

    这是一个可一键部署在 Kubernetes-Istio 集群中的,基于 Golang 的博客微服务 Demo,支持分布式事务. 项目地址:https://github.com/jxlwqq/blog- ...

  3. atomikos实现多数据源支持分布式事务管理(spring、tomcat、JTA)

    原文链接:http://iteye.blog.163.com/blog/static/1863080962012102945116222/   Atomikos TransactionsEssenti ...

  4. Dubbo 支持分布式事务吗?

    目前暂时不支持,可与通过 tcc-transaction 框架实现 介绍:tcc-transaction 是开源的 TCC 补偿性分布式事务框架 Git 地址:https://github.com/c ...

  5. RocketMQ 4.3正式发布,支持分布式事务

      冯嘉 作者 | 冯嘉   近日,Apache RocketMQ 4.3 版本宣布发布,此次发布不仅包括提升性能,减少内存使用等原有特性增强,还修复了部分社区提出的若干问题,更重要的是该版本开源了社 ...

  6. SpringBoot整合mybatis多数据源,支持分布式事务

    编码工具:IDEA SpringBoot版本:2.0.1 JDK版本:1.8 1.使用IDEA构建一个Maven工程 ,添加依赖: <?xml version="1.0" e ...

  7. 分布式事务(三)mysql对XA协议的支持

    系列目录 分布式事务(一)原理概览 分布式事务(二)JTA规范 分布式事务(三)mysql对XA协议的支持 分布式事务(四)简单样例 分布式事务(五)源码详解 分布式事务(六)总结提高 引子 从Mys ...

  8. 【转】PostgreSQL分布式事务配置

    XA是open group提出的分布式事务处理规范,JTA支持XA规范,JTA只规定了接口,有些应用容器提供实现,也有一些三方的开源实现可用,比如Atomikos. 如果PostgreSQL参与分布式 ...

  9. J2EE分布式事务中的提交、回滚方法调用异常。

    这个是昨天上班的时候,写一个后台程序的调试程序时碰到的问题,和项目经理纠结了一天,最后搞定了.于是今天上班正好闲着,花了几乎一天的时间去网上找各种相关的资料.目前了解的内容如此: 根据使用的weblo ...

随机推荐

  1. updateEasyuiTab

    //tabContainer:easyui-tabs或者id,title名称 this.updateEasyuiTab = function (tabContainer, outTitle, outU ...

  2. archive成功了,但是在输出ipa时要求有账号密码

    archive成功了,但是在输出ipa时要求有账号密码 可以通过命令行方式输出,绕开账号检查1.进入Windows-Organizer-Archives,找到要输出的scarchive列表项:2.右键 ...

  3. Spring知识点总结大全(2)

    3.Spring的AOP 一.AOP(Aspect-oriented programming,面向切面编程): 什么是AOP? 定义:将程序中的交叉业务逻辑提取出来,称之为切面.将这些切面动态织入到目 ...

  4. win64

    修改IIS应用程序池,启用支持32位 未能写入输出文件“c:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary AS

  5. .NET J2EE APP全局会话架构运用场景

    .NET J2EE APP全局会话架构运用场景, 全局会话运用拓扑图代码核心架构为.NET架构开发C#语言为主代码架构分为全局会话中心.ASP.NET会话节点..NET会话节点针对WCF服务器与APP ...

  6. 使用Application Insights 做分析

    Application Insights on Windows Desktop apps, services and worker roles : https://azure.microsoft.co ...

  7. 慕课网Java高并发秒杀学习

    课程地址:http://www.imooc.com/learn/587 一个很好:spring,springMVC,mybatis,bootstrap,jQuery,mysql,Restful学习案例 ...

  8. ServiceMix in daemon mode

    For development simplicity, we can start Karaf in daemon mode by executing 'bin\admin.bat start root ...

  9. velocity模板入门

    $!{velocityCount}  随机

  10. mysql 存储 date , datetime问题,初步

    1. java 里的 Date date = new Date()(java.util.Date) 得到  Thu Nov 03 22:19:43 CST 2016, 通过Timestamp stam ...