关于后端:Apache-ShardingSphere-如何实现分布式事务

40次阅读

共计 35207 个字符,预计需要花费 89 分钟才能阅读完成。

陆敬尚,Apache ShardingSphere Committer,SphereEx 基础设施研发工程师,酷爱开源,酷爱数据库技术,目前专一于 Apache ShardingSphere 事务模块的开发。

背景

随着业务的疾速倒退,数据的一直收缩,流量负载的减少,业务零碎遇到了强烈的挑战,对数据库系统可扩展性提出了强烈的诉求。Oracle、MySQL、SQL Server、PostgreSQL 传统单机数据库在线扩大上的问题日益凸显。为了解决扩大问题,呈现了可程度扩大的分布式数据库,于是分布式事务问题成为了必须面对的问题。

在这种背景下,ShardingSphere 提供了一套分布式数据库加强计算引擎,通过可插拔架构构建基于数据库之上的生态系统,提供了分布式事务的能力。

事务介绍

事务语义

事务语义定义了四个个性:原子性(Atomicity)、持久性(Durability)、一致性(Consistency)、隔离性(Isolatation)。

原子性(Atomicity)

在分布式场景下,一个事务的操作可能散布在多个物理节点上,保障在多个节点上的操作都胜利,或都不胜利。

持久性(Durability)

事务提交后,即便断电,事务的操作也是无效的。

一致性(Consistency)

留神:不是 CAP 实践中 C,CAP 中的 C 指的是多正本之间的数据统一问题,这里是不同档次的形象。

站在用户的角度,数据从一个状态,转移到另外一个状态,两个状态都满足肯定的束缚。比方:

银行账户数据,账户 A 有 500 元,账户 B 有 500 元,总额 1000,在一个事务中,执行完 A 和 B 的转账操作后,A 和 B 的账户总额还是 1000。

隔离性(Isolatation)

事务并发执行时,保障并发时数据的正确性。比方:两个事务同时批改一条数据,保障两个事务按肯定程序执行,使数据放弃在一个正确的状态。

面临的挑战

分布式事务绝对单机事务来说面临上面的挑战:

  1. 原子性,对于单机事务来说,应用 undo log 和 redo log 就能够保障全副提交或者全副回滚。而分布式事务波及多个物理节点,每个节点状况是不同的,有的节点日志写胜利,有的节点日志写不胜利。
  2. 网络的不稳固,对于单机来说,通信是稳固的,任何操作都能够失去回复,不管胜利与失败。而分布式场景下,网络是不稳固的,有可能一个操作是得不到回复的,怎么保障分布式事务的可用性(异样事务的清理、复原等)是一个问题。
  3. 并发管制,随着 MVCC 的呈现,操作的可线性化(linearizable)成为了刚需。在单机数据库中,能够很容易地产生全局枯燥递增的事务号,在分布式场景中则不然。

解决方案

原子提交

针对原子性和网络不稳固问题,目前支流的解决方案是 2PC,2PC 定义了两个角色 TM(Transaction Manager)、RM(Resource Manager)。

在分布式场景下,一个事务的操作可能散布在多个节点上,整个事务分两个阶段。

  1. 第一阶段,RM 锁定相干资源并执行具体操作,返回胜利与否给 TM。
  2. 第二阶段,TM 更具第一阶段 RM 返回的后果,如果全副胜利,执行最初的提交操作(事务状态的更改,锁状态删除等),如果有失败的,则回滚。

阐明:当然会有一些优化点,比方不波及多节点的事务转化为一阶段提交等。

留神:两阶段提交协定只解决了提交的问题,要么提交胜利,要么不胜利,不存在局部胜利的中间状态。和事务隔离级别没有必然关系。

并发管制

并发管制,就是保障并发执行的事务在某一种隔离级别上的执行策略。自从多版本控制(MVCC)呈现,支流数据库根本摈弃了以前的两阶段锁模型。

并发管制实质是对数据读和写的并发的管制。并发管制的策略决定了隔离级别,并发管制要解决两个问题。

  1. 决定并发的粒度,比方 MySQL 有行锁(粒度为一行),表锁(粒度为一个表)等
  2. 三种并发场景的行为:

a. 读读并发,不须要非凡解决,因为不波及数据的变更。

b. 写写并发,不能同时并发,否则会产生数据凌乱。

c. 读写并发,性能优化次要在这里做,有多种并发管制机制,根本都抉择了多版本并发管制 (MVCC)。

MVCC 并发管制模型

现有支流实现形式有两种:

  • 基于事务 ID 和 ReadView

每次事务获取事务 ID,标识事务的开启程序,通过沉闷事务列表来获取快照,存储多个以事务 ID 为版本的数据,从而达到并发管制的成果。MySQL、Postgres-XL 都是采取的这种计划。

  • 基于 timestamp

引入 timestamp,通过在数据中增加 timestamp 相干属性,通过比照数据的 commitTs(commit timestamp)和 Snapshot timestamp 来判断可见性,从而达到可线性化的并发管制成果。Spanner 采纳的这种计划。

下面两种计划都离不开全局事务号的生成,常见的全局事务号生成机制有 TrueTime(Spanner 采纳),HLC(CockroachDB 采纳有误差的 HLC),TSO(Timestamp Oracle),具体原理见参考文献。

ShardingSphere 事务设计

ShardingSphere 事务性能建设在存储 DB 的本地事务之上,提供 LOCAL、XA、BASE 三种模式事务,使用者只需应用原生事务形式(begin/commit/rollback),就能够应用三种模式,在一致性和性能做适合的衡量。

LOCAL

LOCAL 模式间接建设在存储 DB 的本地事务上的,会存在肯定的原子性问题,当然性能是最高的,如果能够容忍这个问题,这将是一个不错的抉择。

XA

XA 模式,XA 协定是基于 2PC 定义的一套交互协定,定义了 xa start/prepare/end/commit/rollback 等接口,罕用的实现有 Narayana、Atomics,ShardingSphere 集成了 Narayana、Atomics 的 XA 实现。

  1. app 连贯到 Proxy 上,Proxy 创立一个 session 的对象和这个 connection 绑定。
  2. app 执行 begin,Proxy 通过 Narayana TM 新建一个逻辑 transaction,和以后 session 绑定。
  3. app 执行具体 SQL,session 负责建设到存储 DB 的 connection,并把 connection 通过 Transaction.enlistResource() 接口把 connection 注册到 transaction,执行 XA START {XID} 开启事务,并执行路由改写后的 SQL。
  4. app 执行 commit 命令,transaction 中注册的连贯存储 DB 的 connection,别离执行 xa prepare,当所有 connection 返回 ok,更新 transaction 状态为 prepared,每个 connection 执行 xa commit,都返回 ok 更新 transaction 状态为 commited,提交胜利。如果 prepare 过程局部失败,用户能够通过 rollback 命令登程回滚,不解决则有后盾过程进行清理。
  5. app 执行 rollback 命令,transaction 中注册的连贯存储 DB 的 connection,别离执行 xa rollback,进行回滚。

BASE

Base(Basically Available, Soft State, Eventually Consistent)模式,BASE 事务是 CAP 实践中 C 和 A 衡量的后果,Seata 的 AT 模式是 Base 事务的一种实现,ShardingSphere 集成了 Seata 的 AT 实现。

  1. app 连贯到 Proxy 上,Proxy 创立一个 session 的对象和这个 connection 绑定。
  2. app 执行 begin,Proxy 通过 Seata TM 新建一个逻辑 transaction,和以后 session 绑定,并注册到 Seata Server。
  3. app 执行一条逻辑 SQL,session 负责建设到存储 DB 的 connection,每个 connection 是 Seata 的 ConnectionProxy 实例,对路由改写后的 actual sql 进行解析, 做一些拦挡,比方:如果是批改操作,执行 begin 获取本地锁,执行一条 SQL,执行 commit 开释本地锁,上报分支事务后果到 Seata Server。
  4. app 执行 commit 命令,Proxy 中的 Seata TM 告诉 Seata Server 后,间接返回 app,Seata Server 异步和 Proxy 交互,进行删除事务日志。
  5. app 执行 rollback 命令,Proxy 中的 Seata TM 告诉 Seata Server 后,间接返回 app,Seata Server 异步和 Proxy 交互,执行弥补操作,删除事务日志。

具体流程参考 Seata 官网。

应用示例

安装包筹备

以反对较好的 XA,集成 Narayana 的实现为例,进行介绍。因为 Narayana 的 License 问题,不能间接打包到安装包内,须要增加额定的依赖。

依据官网下载好安装包,解压到 ${ShardingSphere} 目录,往 ${ShardingSphere}/lib 目录下增加以下 jar 包。(下载地址:https://mvnrepository.com/)

<div class=”output_wrapper” id=”output_wrapper_id” style=”font-size: 16px; color: rgb(62, 62, 62); line-height: 1.6; word-spacing: 0px; letter-spacing: 0px; font-family: ‘Helvetica Neue’, Helvetica, ‘Hiragino Sans GB’, ‘Microsoft YaHei’, Arial, sans-serif;”><pre style=”font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px;”>jta<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">-5.12</span><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">.4</span>.<span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">Final</span>.jar
arjuna<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">-5.12</span><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">.4</span>.<span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">Final</span>.jar
common<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">-5.12</span><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">.4</span>.<span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">Final</span>.jar
jboss-connector-api_1<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">.7</span>_spec<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">-1.0</span><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">.0</span>.<span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">Final</span>.jar                                             | ------------------------------------------------------------------------------------------------------------------------------------
jboss-logging<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">-3.2</span><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">.1</span>.<span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">Final</span>.jar                                                    | ------------------------------------------------------------------------------------------------------------------------------------
jboss-transaction-api_1<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">.2</span>_spec<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">-1.0</span><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">.0</span>.Alpha3.jar                                           | ------------------------------------------------------------------------------------------------------------------------------------
jboss-transaction-spi<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">-7.6</span><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">.0</span>.<span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">Final</span>.jar
mysql-connector-java<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">-5.1</span><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">.47</span>.jar                                                   | ------------------------------------------------------------------------------------------------------------------------------------
narayana-jts-integration<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">-5.12</span><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">.4</span>.<span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">Final</span>.jar
shardingsphere-transaction-xa-narayana<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">-5.1</span><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">.1</span>-SNAPSHOT.jar

MySQL 实例筹备

  1. 筹备两个 MySQL 实例,127.0.0.1:3306,127.0.0.1:3307。
  2. 两个 MySQL 实例别离创立用户 root, 明码为 12345678。
  3. 两个 MySQL 实例别离创立 test 库。

ShardingSphere-Proxy 配置

批改 server.yaml 事务配置

<div class=”output_wrapper” id=”output_wrapper_id” style=”font-size: 16px; color: rgb(62, 62, 62); line-height: 1.6; word-spacing: 0px; letter-spacing: 0px; font-family: ‘Helvetica Neue’, Helvetica, ‘Hiragino Sans GB’, ‘Microsoft YaHei’, Arial, sans-serif;”><pre style=”font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px;”><span class="hljs-symbol" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(42, 146, 146); word-wrap: inherit !important; word-break: inherit !important;">rules:</span>
  - !AUTHORITY
    <span class="hljs-symbol" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(42, 146, 146); word-wrap: inherit !important; word-break: inherit !important;">users:</span>
      - root@%<span class="hljs-symbol" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(42, 146, 146); word-wrap: inherit !important; word-break: inherit !important;">:root</span>
      - sharding@<span class="hljs-symbol" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(42, 146, 146); word-wrap: inherit !important; word-break: inherit !important;">:sharding</span>
    <span class="hljs-symbol" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(42, 146, 146); word-wrap: inherit !important; word-break: inherit !important;">provider:</span>
      <span class="hljs-symbol" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(42, 146, 146); word-wrap: inherit !important; word-break: inherit !important;">type:</span> ALL_PRIVILEGES_PERMITTED
  - !TRANSACTION
    <span class="hljs-symbol" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(42, 146, 146); word-wrap: inherit !important; word-break: inherit !important;">defaultType:</span> XA
    <span class="hljs-symbol" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(42, 146, 146); word-wrap: inherit !important; word-break: inherit !important;">providerType:</span> Narayana

批改 conf/conf-sharding.yaml

<div class=”output_wrapper” id=”output_wrapper_id” style=”font-size: 16px; color: rgb(62, 62, 62); line-height: 1.6; word-spacing: 0px; letter-spacing: 0px; font-family: ‘Helvetica Neue’, Helvetica, ‘Hiragino Sans GB’, ‘Microsoft YaHei’, Arial, sans-serif;”><pre style=”font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px;”>dataSources:
  ds_0:
    url: jdbc:mysql://127.0.0.1:3306/<span class="hljs-built_in" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">test</span>?serverTimezone=UTC&allowPublicKeyRetrieval=<span class="hljs-literal" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">true</span>&useSSL=<span class="hljs-literal" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">false</span>
    username: root
    password: 12345678
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1
  ds_1:
    url: jdbc:mysql://127.0.0.1:3307/<span class="hljs-built_in" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">test</span>?serverTimezone=UTC&allowPublicKeyRetrieval=<span class="hljs-literal" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">true</span>&useSSL=<span class="hljs-literal" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">false</span>
    username: root
    password: 12345678
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1

rules:
  - !SHARDING
    tables:
      account:
        actualDataNodes: ds_<span class="hljs-variable" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(190, 70, 120); word-wrap: inherit !important; word-break: inherit !important;">${0..1}</span>.account<span class="hljs-variable" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(190, 70, 120); word-wrap: inherit !important; word-break: inherit !important;">${0..1}</span>
        tableStrategy:
          standard:
            shardingColumn: id
            shardingAlgorithmName: account_inline
        keyGenerateStrategy:
          column: id
          keyGeneratorName: snowflake
    defaultDatabaseStrategy:
      standard:
        shardingColumn: id
        shardingAlgorithmName: database_inline
    defaultTableStrategy:
      none:

    shardingAlgorithms:
      database_inline:
        <span class="hljs-built_in" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">type</span>: INLINE
        props:
          algorithm-expression: ds_<span class="hljs-variable" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(190, 70, 120); word-wrap: inherit !important; word-break: inherit !important;">${id&nbsp;%&nbsp;2}</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;account_inline:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="hljs-built_in" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">type</span>:&nbsp;INLINE<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;props:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;algorithm-expression:&nbsp;account<span class="hljs-variable" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(190, 70, 120); word-wrap: inherit !important; word-break: inherit !important;">${id % 2}</span>

    keyGenerators:
      snowflake:
        <span class="hljs-built_in" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">type</span>: SNOWFLAKE
        props:
          worker-id: 123

启动 ShardingSphere-Proxy

参考如下命令启动 Proxy:

<div class=”output_wrapper” id=”output_wrapper_id” style=”font-size: 16px; color: rgb(62, 62, 62); line-height: 1.6; word-spacing: 0px; letter-spacing: 0px; font-family: ‘Helvetica Neue’, Helvetica, ‘Hiragino Sans GB’, ‘Microsoft YaHei’, Arial, sans-serif;”><pre style=”font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px;”><span class="hljs-built_in" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">cd</span> <span class="hljs-variable" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(190, 70, 120); word-wrap: inherit !important; word-break: inherit !important;">${ShardingSphere}</span>
./bin/start.sh

应用 ShardingSphere-Proxy

应用 MySQL Client 连贯 ShardingSphere-Proxy 进行测试,参考如下命令。

<div class=”output_wrapper” id=”output_wrapper_id” style=”font-size: 16px; color: rgb(62, 62, 62); line-height: 1.6; word-spacing: 0px; letter-spacing: 0px; font-family: ‘Helvetica Neue’, Helvetica, ‘Hiragino Sans GB’, ‘Microsoft YaHei’, Arial, sans-serif;”><pre style=”font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px;”><span class="hljs-selector-tag" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">mysql</span> <span class="hljs-selector-tag" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">-h127</span><span class="hljs-selector-class" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(190, 70, 120); word-wrap: inherit !important; word-break: inherit !important;">.0</span><span class="hljs-selector-class" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(190, 70, 120); word-wrap: inherit !important; word-break: inherit !important;">.0</span><span class="hljs-selector-class" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(190, 70, 120); word-wrap: inherit !important; word-break: inherit !important;">.1</span> <span class="hljs-selector-tag" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">-P3307</span> <span class="hljs-selector-tag" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">-uroot</span> <span class="hljs-selector-tag" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">-proot</span>

<div class=”output_wrapper” id=”output_wrapper_id” style=”font-size: 16px; color: rgb(62, 62, 62); line-height: 1.6; word-spacing: 0px; letter-spacing: 0px; font-family: ‘Helvetica Neue’, Helvetica, ‘Hiragino Sans GB’, ‘Microsoft YaHei’, Arial, sans-serif;”><pre style=”font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px;”>mysql> use sharding_db;
Database changed
mysql> <span class="hljs-function" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">create table <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(87, 109, 219); word-wrap: inherit !important; word-break: inherit !important;">account</span>(<span class="hljs-params" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">id <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">int</span>, balance <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">float</span> ,transaction_id <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">int</span></span>)</span>;
Query OK, <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">0</span> <span class="hljs-function" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">rows <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(87, 109, 219); word-wrap: inherit !important; word-break: inherit !important;">affected</span> (<span class="hljs-params" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;"><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">0.12</span> sec</span>)

mysql> <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">select</span>  <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">from</span> account</span>;
<span class="hljs-function" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">Empty <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(87, 109, 219); word-wrap: inherit !important; word-break: inherit !important;">set</span> (<span class="hljs-params" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;"><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">0.02</span> sec</span>)

mysql> begin</span>;
Query OK, <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">0</span> <span class="hljs-function" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">rows <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(87, 109, 219); word-wrap: inherit !important; word-break: inherit !important;">affected</span> (<span class="hljs-params" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;"><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">0.09</span> sec</span>)

mysql> insert <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">into</span> <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(87, 109, 219); word-wrap: inherit !important; word-break: inherit !important;">account</span>(<span class="hljs-params" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">id, balance, transaction_id</span>) <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(87, 109, 219); word-wrap: inherit !important; word-break: inherit !important;">values</span>(<span class="hljs-params" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;"><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">1</span>,<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">1</span>,<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">1</span></span>),(<span class="hljs-params" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;"><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">2</span>,<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">2</span>,<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">2</span></span>)</span>;
Query OK, <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">2</span> <span class="hljs-function" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">rows <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(87, 109, 219); word-wrap: inherit !important; word-break: inherit !important;">affected</span> (<span class="hljs-params" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;"><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">0.53</span> sec</span>)

mysql> <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">select</span>  <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">from</span> account</span>;
+------+---------+----------------+
| id  | balance | transaction_id |
+------+---------+----------------+
|  <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">2</span> |   <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">2.0</span> |       <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">2</span> |
|  <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">1</span> |   <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">1.0</span> |       <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">1</span> |
+------+---------+----------------+
<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">2</span> <span class="hljs-function" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">rows <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">in</span> <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(87, 109, 219); word-wrap: inherit !important; word-break: inherit !important;">set</span> (<span class="hljs-params" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;"><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">0.03</span> sec</span>)

mysql> commit</span>;
Query OK, <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">0</span> <span class="hljs-function" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">rows <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(87, 109, 219); word-wrap: inherit !important; word-break: inherit !important;">affected</span> (<span class="hljs-params" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;"><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">0.05</span> sec</span>)

mysql> <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">select</span> * <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">from</span> account</span>;
+------+---------+----------------+
| id  | balance | transaction_id |
+------+---------+----------------+
|  <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">2</span> |   <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">2.0</span> |       <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">2</span> |
|  <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">1</span> |   <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">1.0</span> |       <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">1</span> |
+------+---------+----------------+
<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">2</span> <span class="hljs-function" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">rows <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">in</span> <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(87, 109, 219); word-wrap: inherit !important; word-break: inherit !important;">set</span> (<span class="hljs-params" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;"><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">0.02</span> sec</span>)
</span>

将来布局

当初 ShardingSphere 的分布式事务集成了第三方的 2PC 实现计划,提供了原子性的保障,隔离性依赖于存储 DB 的隔离保障,提供了可用的事务性能。将来基于全局 Timestamp 实现 MVCC,联合 2PC,对事务隔离语义提供更好的反对。欢送大家关注 ShardingSphere 的成长。

如果大家对 Apache ShardingSphere 有任何疑难或倡议,欢送在 GitHub issue 列表提出,或可返回中文社区交换探讨。

GitHub issue:https://github.com/apache/shardingsphere/issues

奉献指南:https://shardingsphere.apache.org/community/cn/contribute/

中文社区:https://community.sphere-ex.com/

参考文献

1.ACID wiki:https://en.wikipedia.org/wiki/ACID

2.ANSI isolation levels:https://renenyffenegger.ch/notes/development/databases/SQL/transaction/isolation-level

3.《Distributed Transactions Are Evil》:https://wiki.c2.com/?DistributedTransactionsAreEvil

4.《Distributed transactions and why you should care》:https://towardsdatascience.com/distributed-transactions-and-why-you-should-care-116b6da8d72

5.《Fault-Tolerant Stream Processing at Internet Scale》:http://static.googleusercontent.com/media/research.google.com/en/us/pubs/archive/41378.pdf

6.《Oracle Two Phase Commit 2PC Tips》:http://www.dba-oracle.com/t_two_phase_commit_2pc.htm

7.《2PC: Concurrency Control and Recovery in Database Systems》:https://courses.cs.washington.edu/courses/cse551/09au/papers/CSE550BHG-Ch7.pdf

8.《An Empirical Evaluation of In-Memory Multi-Version Concurrency Control》:https://15721.courses.cs.cmu.edu/spring2018/papers/05-mvcc1/wu-vldb2017.pdf

9.《Concurrency Control And Recovery In Database Systems》:https://courses.cs.washington.edu/courses/cse551/09au/papers/CSE550BHG-Ch7.pdf

10.《Optimistic Concurrency Control》:[https://15721.courses.cs.cmu….)]()

11.《Base: An Acid Alternative》:https://queue.acm.org/detail.cfm?id=1394128

12.《Jepsen: CockroachDB beta-20160829》:https://jepsen.io/analyses/cockroachdb-beta-20160829

13.《Spanner: Google’s Globally-Distributed Database》:https://static.googleusercontent.com/media/research.google.com/en//archive/spanner-osdi2012.pdf

欢送增加社区经理微信(ss_assistant_1)退出交换群,与泛滥 ShardingSphere 爱好者一起交换。

正文完
 0