系统经sharding改造之后,原来单一的数据库会演变成多个数据库,如何确保多数据源同时操作的原子性和一致性是不得不考虑的一个问题。总体上看,目前对于一个分布式系统的事务处理有三种方式:分布式事务、基于Best Efforts 1PC模式的事务以及事务补偿机制。我们下面对这三种处理方式一一进行分析。
分布式事务
这是最为人们所熟知的多数据源事务处理机制。本文并不打算对分布式事务做过多介绍,读者可参考此文:关于分布式事务、两阶段提交、一阶段提交、Best Efforts 1PC模式和事务补偿机制的研究 。在这里只想对分布式事务的利弊作一下分析。
 
优势:
1. 基于两阶段提交,最大限度地保证了跨数据库操作的“原子性”,是分布式系统下最严格的事务实现方式。
2. 实现简单,工作量小。由于多数应用服务器以及一些独立的分布式事务协调器做了大量的封装工作,使得项目中引入分布式事务的难度和工作量基本上可以忽略不计。
 
劣势:
系统“水平”伸缩的死敌。基于两阶段提交的分布式事务在提交事务时需要在多个节点之间进行协调,最大限度地推后了提交事务的时间点,客观上延长了事务的执行时间,这会导致事务在访问共享资源时发生冲突和死锁的概率增高,随着数据库节点的增多,这种趋势会越来越严重,从而成为系统在数据库层面上水平伸缩的”枷锁”, 这是很多Sharding系统不采用分布式事务的主要原因。
 
基于Best Efforts 1PC模式的事务
与分布式事务采用的两阶段提交不同,Best Efforts 1PC模式采用的是一阶段端提交,牺牲了事务在某些特殊情况(当机、网络中断等)下的安全性,却获得了良好的性能,特别是消除了对水平伸缩的桎酷。Distributed transactions in Spring, with and without XA一文对Best Efforts 1PC模式进行了详细的说明,该文提供的Demo代码更是直接给出了在Spring环境下实现一阶段提交的多数据源事务管理示例。不过需要注意的是,原示例是基于spring 3.0之前的版本,如果你使用spring 3.0+,会得到如下错误:java.lang.IllegalStateException: Cannot activate transaction synchronization – already active,如果使用spring 3.0+,你需要参考spring-data-neo4j的实现。鉴于Best Efforts 1PC模式的性能优势,以及相对简单的实现方式,它被大多数的sharding框架和项目采用。
 
事务补偿机制
对于那些对性能要求很高,但对一致性要求并不高的系统,往往并不苛求系统的实时一致性,只要在一个允许的时间周期内达到最终一致性即可,这使得事务补偿机制成为一种可行的方案。事务补偿机制最初被提出是在“长事务”的处理中,但是对于分布式系统确保一致性也有很好的参考意义。笼统地讲,与事务在执行中发生错误后立即回滚的方式不同,事务补偿是一种事后检查并补救的措施,它只期望在一个容许时间周期内得到最终一致的结果就可以了。事务补偿的实现与系统业务紧密相关,并没有一种标准的处理方式。一些常见的实现方式有:对数据进行对帐检查;基于日志进行比对;定期同标准数据来源进行同步,等等。
 
小结
分布式事务,最严格的事务实现,但性能是个大问题;Best Efforts 1PC模式,性能与事务可靠性的平衡,支持系统水平伸缩,大多数情况下是最合适的选择;事务补偿机制,只能适用于对事务性要求不高,允许数据“最终一致”即可的系统,牺牲实时一致性,获得最大的性能回报。

DB 分库分表(4):多数据源的事务处理的更多相关文章

  1. DB 分库分表的基本思想和切分策略

    DB 分库分表的基本思想和切分策略 一.基本思想 Sharding的基本思想就要把一个数据库切分成多个部分放到不同的数据库(server)上,从而缓解单一数据库的性能问题.不太严格的讲,对于海量数据的 ...

  2. DB 分库分表(5):一种支持自由规划无须数据迁移和修改路由代码的 Sharding 扩容方案

    作为一种数据存储层面上的水平伸缩解决方案,数据库Sharding技术由来已久,很多海量数据系统在其发展演进的历程中都曾经历过分库分表的Sharding改造阶段.简单地说,Sharding就是将原来单一 ...

  3. DB 分库分表(2):全局主键生成策略

    DB 分库分表(2):全局主键生成策略 本文将主要介绍一些常见的全局主键生成策略,然后重点介绍flickr使用的一种非常优秀的全局主键生成方案.关于分库分表(sharding)的拆分策略和实施细则,请 ...

  4. DB 分库分表(1):拆分实施策略和示例演示

    DB 分库分表(1):拆分实施策略和示例演示 第一部分:实施策略 1.准备阶段 对数据库进行分库分表(Sharding化)前,需要开发人员充分了解系统业务逻辑和数据库schema.一个好的建议是绘制一 ...

  5. DB 分库分表(3):关于使用框架还是自主开发以及 sharding 实现层面的考量

    当团队对系统业务和数据库进行了细致的梳理,确定了切分方案后,接下来的问题就是如何去实现切分方案了,目前在sharding方面有不少的开源框架和产品可供参考,同时很多团队也会选择自主开发实现,而不管是选 ...

  6. 三、SpringBoot 整合mybatis 多数据源以及分库分表

    前言 说实话,这章本来不打算讲的,因为配置多数据源的网上有很多类似的教程.但是最近因为项目要用到分库分表,所以让我研究一下看怎么实现.我想着上一篇博客讲了多环境的配置,不同的环境调用不同的数据库,那接 ...

  7. 基于AOP和HashMap原理学习,开发Mysql分库分表路由组件!

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 什么?Java 面试就像造火箭 单纯了! 以前我也一直想 Java 面试就好好面试呗 ...

  8. Django 数据库读写分离 分库分表

    多个数据库 配置: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BA ...

  9. 超实用的mysql分库分表策略,轻松解决亿级数据问题

    一.分库分表的背景 在数据爆炸的年代,单表数据达到千万级别,甚至过亿的量,都是很常见的情景.这时候再对数据库进行操作就是非常吃力的事情了,select个半天都出不来数据,这时候业务已经难以维系.不得已 ...

随机推荐

  1. JS基础_for循环练习3

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. 养成一个SQL好习惯

    要知道sql语句,我想我们有必要知道sqlserver查询分析器怎么执行我么sql语句的,我么很多人会看执行计划,或者用profile来监视和调优查询语句或者存储过程慢的原因,但是如果我们知道查询分析 ...

  3. 初识python之了解程序设计基本方法

    对于用计算机解决一些问题,这里有一个程序设计的基本方法,主要分为六个步骤,其分析和实现过程如下: (1)分析问题:利用计算机解决问题需要结合计算机技术的发展水平和人类对问题的思考程度,在特定技术和社会 ...

  4. 解决IDEA报错Could not autowire. There is more than one bean of 'xxx' type

    更新项目之后IDEA突然出现了这样的报错信息.显示Could not autowire. There is more than one bean of 'xxx' type.这个错误的意思是xxx类型 ...

  5. IntelliJ IDEA 接口类跳转到实现类及实现类跳转到接口

    接口和实现类的互相跳转是使用IntelliJ IDEA过程中常用的操作,在此记录一下: 1.Service接口跳转到实现类 操作:在接口类的方法上使用快捷键Ctrl+Alt+B,或者点击下图所示位置 ...

  6. navicat连接阿里云mysql

    1.服务器控制台在安全组配置3306端口 2.进入 /etc/ssh/sshd_config 在最下面 加入下面代码 KexAlgorithms diffie-hellman-group1-sha1, ...

  7. Delphi BuildCommDCBAndTimeouts函数

  8. leetcode第6题:Z字形变换--直接模拟求解法

    [题目描述] 将一个给定字符串根据给定的行数,以从上往下.从左到右进行 Z 字形排列. 比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下: 之后,你 ...

  9. 【vue lazyload】插件的使用步骤

    VUE图片懒加载-vue lazyload插件的简单使用

  10. python学习笔记-(十三)线程、进程、多线程&多进程

    为了方便大家理解下面的知识,可以先看一篇文章:http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html 线程 1.什么是线程? ...