43
在 ongoDB 中实现强事务

在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

Embed Size (px)

Citation preview

Page 1: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

在 ongoDB 中实现强事务

Page 2: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

{ name: “TJ Tang/唐建法”,

title: “MongoDB 大中华区首席技术顾问”, des: “mongoing.com 中文社区发起人”,

email: “[email protected]”, wechat:“tjtang826”

}

关于讲师

Page 3: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

MongoDB 介绍

ACID事务

事务补偿设计模式

mongosaga – 事务补偿框架

关于今天的分享

Page 4: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

MongoDB 介绍

Page 5: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

     

600+  employees   MongoDB Inc. 原10gen公司 MongoDB开源代码贡献者

     

2,000+  customers  

     

13  offices  worldwide  

     

15,000,000+  Downloads  

Page 6: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

RANK   DBMS          MODEL   SCORE   GROWTH  (20  MO)  

1.   Oracle   Rela+onal  DBMS   1,442   -­‐5%  

2.   MySQL   Rela+onal  DBMS   1,294   2%  

3.   Microso?  SQL  Server   Rela+onal  DBMS   1,131   -­‐10%  

4.   MongoDB   Document  Store   277   172%  

5.   PostgreSQL   Rela+onal  DBMS   273   40%  

6.   DB2   Rela+onal  DBMS   201   11%  

7.   Microso?  Access   Rela+onal  DBMS   146   -­‐26%  

8.   Cassandra   Wide  Column   107   87%  

9.   SQLite   Rela+onal  DBMS   105   19%  

Source: DB-engines database popularity rankings; May 2015

最流行、发展最快的分布式数据库

Page 7: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

高性能,水平扩展

Always On 全球部署

灵活的模式 丰富的查询语句  

⼆二级索引  

事务支持,Join

企业工具集成

MongoDB:新一代架构NewSQL数据库

关系型 非关系型

NewSQL

Page 8: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

高可用 Replica Set

水平扩展 Sharding

灵活动态 文档模型

MongoDB的特点

Page 9: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

{ ! first_name: ‘Paul’,! surname: ‘Miller’,! city: ‘London’,! location: [45.123,47.232],! cars: [ ! { model: ‘Bentley’,! year: 1973,! value: 100000, … },! { model: ‘Rolls Royce’,! year: 1965,! value: 330000, … }! ]!}!

文档模型的优点

丰富的结构 JSON文档结构可以直接表达复杂对象结构 非常接近In Memory数据模型 动态的模式 可以随时增加、修改结构,无需数据迁移

快速开发 无需建模 程序接口自然无需ORM

Page 10: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

10

高可用,自动故障切换

多数据中心支持,自动容灾

滚动维护无下线

读写分离

多变易用复制集

Page 11: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

自动均衡

自动路由分发请求

运维透明化, 底层部署不影响应用

横向扩展支持海量的数据及并发

Page 12: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

社区版 MongoDB Community 企业版 MongoDB Enterprise Advanced

MongoDB Core Server ✔   ✔  

Replication and Sharding ✔   ✔  

Aggregation Framework ✔   ✔  

Security: Role-Based Access Control, PKI Certificates, SSL, Field-Level Redaction ✔   ✔

Advanced Security: LDAP Authentication, Kerberos Authentication, x.509 Certificates, Auditing

Automated Deploy, Configuration, Maintenance, Zero Downtime Upgrades ✔

Backup and Point-In-Time Recovery ✔

Monitoring and Alerting ✔

Encrypted & In-Memory Storage Engines ✔

MongoDB Compass ✔

MongoDB Connector for BI ✔

On-Demand Training ✔

Support SLA 1 hr

License Type AGPL Commercial

Page 13: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

•  用户管理 •  电商、产品目录 •  游戏 •  实时分析 •  仓储管理 •  购物车 •  IM应用 •  广告 •  社交应用

MongoDB适用场景

•  账单查询 •  客户管理 •  风险分析 •  ECM •  参考数据 •  360度视图

•  内容管理系统CMS •  物联网 •  车联网 •  数据即服务 •  通用数据平台 •  地理位置系统 •  高速缓存

RDBMS能做的,MongoDB基本都能做!

RDBMS不能做的,MongoDB还是能做!

Page 14: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

可是,听说MongoDB不支持强事务?

Page 15: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

!

常见数据库的事务支持

数据库 事务支持程度

Oracle DB2 SQL Server MySQL PostgreSQL

支持ACID

MongoDB Cassandra Couchbase

支持单文档ACID

Page 16: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

关于ACID事务

ACID

Consistency 一致性

Atomicity 原子性

Durability 持久性

Isolation 隔离性 数据持久存在, 哪怕宕机后

All or Nothing 要么全部提交, 要么回滚

在事务范围内看到的数据前后一致,并且符合既定数据库规则如外键

你对数据的操作对其他用户不可见,直到提交为止

Page 17: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

!

ACID简化编程

@Transactional!public void transfer(from, to, amount) {! try{!

!begin()!!debit(from, amount);!!credit(to, amount);!!commit();!

}! catch(Exception e){!

!rollback();! }!}!

public boolean transfer(from, to, amount) { double origBalance = readBalance(from);! double origBalance2 = readBalance(to);! boolean creditOk = false, debitOk=false,! try{!

!synchronized(from) {!! synchronized(to) {!! debit(from, amount); ! credit(to, amount);!! double newBalance = readBalance(from);

if(newBalance != origBalance – amount)!! ! throw new Exception(“wrong”);!! }!!}!

}! catch(Exception e){!

! // if debit has been done! undoDebit(from, amount);!

! return false;! }! return true; !!}!

经典案例:小明转账100元给小红

数据库实现事务

应用实现事务

Page 18: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

!

MongoDB的单文档事务性

场景 事务性

db.employee.update({ _id: 100}, {! $inc: { salary: 10000 },! $set: { level: 10 }! } !)!

支持单文档内原子性和隔离性: $inc 和 $set

db.employee.update({ level:9}, {! $inc: { salary: 10000 },! } !)!

更新多个文档时候不能保证全部更新或全部不更新,无回滚行为

db.employee.update(…) db.salary.update(…) !

不能保证全部更新或全部不更新,无回滚行为

Page 19: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

为什么不支持Full ACID?

ACID 是为 单机设计的

POIN   POINT  分布式事务通常 需要二阶段提交

二阶段提交 性能差 问题多

如果不能提供 高性能ACID, 还不如先实现 更有意义的功能

目前还没有生产 级别的高性能

分布式事务数据库

Page 20: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

!

二阶段提交

1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

Transac+on  Manager

Can commit?

Yes

commit

phase 1: prepare

Phase 2: commit

DB Queue

http://www.oracle.com/technetwork/products/clustering/overview/distributed-transactions-and-xa-163941.pdf

3. 无法保证节点之间强一致! T1: 01.000 DB和Queue同时commit T2: 01.050 Queue commit 完成 T3: 01.200 这时候去读DB&Queue? T4: 01.500 DB commit 完成(或者commit失败)

T2 T4 T1 T1

Page 21: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

!

CAP 定理 – 2000年

Eric  Brewer  Professor,  UC  Berkeley    VP  Infrastructure,  Google

2000年版本

Page 22: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

CAP 定理 – 2012年

数据允许暂时的不一致,只要最终一

操作对其他线程可见

Page 23: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

强一致 vs 最终一致

Full ACID 强一致 非分布式 无大规模并发

Partial ACID 最终一致 分布式 大规模并发

Page 24: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

强事务:你到底想要什么?

public void transfer(from, to, amount){!!debit(from, amount);!!credit(to, amount);!

}!

All or Nothing 原子性 全部提交或回滚

Page 25: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

Saga事务:补偿机制

ATM 订单 跨行转账 电信扣费 . . .

•  多个相对独立的操作,各自提交

•  某个步骤出错时启用补偿机制,消除之前操作的效果

•  无全局事务锁,可实现分布式高并发

•  提供原子性的事务支持

Transaction Compensation

Page 26: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

一个订单的例子

hRps://msdn.microso?.com/en-­‐us/library/dn589800.aspx

订单处理步骤: 1. 减库存 2. 保存订单 3. 扣款

               

               

补偿操作

最终状态 操作

库存减掉 订单保存 扣款成功

系统已经一致

库存已减 订单未保存

1.  恢复库存

2.  系统达成一致

库存已减 订单保存 但是扣款未成功

1.  恢复库存

2.  修改订单状态为取消

3.  系统达成一致

Page 27: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

!

事务补偿伪代码

public boolean placeOrder(order) {!!!!boolean inventoryUpdated,orderSaved, paymentReceived;!

!!inventoryUpdated = subtractInventory(order.sku, order.quantity);!

!!if(inventoryUpdated){!! !orderSaved = saveOrder(order);!! !if(orderSaved)!! ! !paymentReceived = processPayment(order);!!}!

!!if(!paymentReceived){!! !if(orderSaved)!! ! !updateOrderStatus(order, "canceled");!! !if(inventoryUpdated)!! ! !addInventory(order.sku, order.quantity);!!}!!else if(!orderSaved){!! !if(inventoryUpdated)!! ! !addInventory(order.sku, order.quantity);!!}!

}!

订单处理三部曲:减库存,保存订单,订单支付

Page 28: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

!

我明白了,可是这个代码有点不好看⋯

Page 29: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

mongosaga

基于Spring Framework的补偿式事务组件

帮助你在MongoDB里面实现分布式事务

https://github.com/tjworks/mongosaga

Page 30: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

工作原理– 正常模式

•  基于Spring AOP

•  Java Annotation

•  自动注入Proxy

•  记录事务范围内所有可补偿操作(enlist)

Page 31: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

工作模式 – 补偿模式

•  Credit 步骤失败

•  确定需要补偿的操作 getCompensations()

•  自动调用补偿器 undoCredit()

Page 32: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

如何使用 1-2-3

1. 下载mongosaga jar 文件或者直接在POM.xml里面用 maven dependency

<dependency> <groupId>com.mongoing.mongosaga</groupId> <artifactId>mongosaga</artifactId> <version>0.5 </version> </dependency>

2. 对需要事务的方法加一个 @Compensatable 标注 3. 对该事务内的每一个操作实现一个补偿器(方法)

Page 33: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

演示步骤 1

Clone或者下载 mongosaga 项目(包含测试代码)

# git clone https://github.com/tjworks/mongosaga!

AccountManager.java    

transfer()

Account.java              debit()            debit_compensator()            credit()            credit_compensator()  

LoadTest.java    

testTransfer()

Page 34: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

演示步骤 2

在test目录下定义AccountManager类,把需要在一个事务内完成的操作封装在一个方法里,使用@Compensatable 来标注该方法启用补偿事务 package com.mongoing.mongosaga;!!public class AccountManager {!! @autowired! Account account;!! @Compensatable !!

public void transfer(from, to, amount) {!!account.debit(from, amount);!!account.credit(to, amount);!

}!!}!

Page 35: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

演示步骤 3

public class Account {! . . .! private DBCollection accounts;! ! @Compensate! public void debit(String from, double amount){! log.info("debit " + amount+" from account "+from);! accounts.update(new BasicDBObject("name", from), ! new BasicDBObject("$inc", new BasicDBObject("balance", -1* amount)));! }! public void debit_compensator(String from, double amount){! log.info(“compensating debit operation, adding " + amount+" back to "+from); ! accounts.update(new BasicDBObject("name", from), ! new BasicDBObject("$inc", new BasicDBObject("balance", amount)));! }! ! @Compensate! public void credit(String to, double amount){! log.info("credit "+ amount+" to "+to);! accounts.update(new BasicDBObject("name", to), ! new BasicDBObject("$inc", new BasicDBObject("balance", amount)));! }! public void credit_compensator(String to, double amount){! log.info(”compensating credit operation, subtract " + amount+" from "+to); ! accounts.update(new BasicDBObject("name", to), ! new BasicDBObject("$inc", new BasicDBObject("balance", -1* amount)));! } !!

增加一个Account类, 为每一个需要补偿的操作(方法)在同一个类内创建一个补偿器方法, 补偿器方法命名规则: 原方法名+ “_compensator”

补偿器

Page 36: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

演示步骤 4

. . .! final class Worker implements Runnable {! int id;! public Worker(int id){ this.id=id; }! public void run(){! int amount = (int)(Math.random()*100)+1;! for(int k=0;k<1000;k++){! try{! counter[0]++;! accountManager.transfer("mona"+ id, "tj"+ id, amount); ! }! catch(Exception e){ counter[1]++; } ! } ! }! } ! int poolSize = 100;! ExecutorService executor = Executors.newFixedThreadPool(poolSize); ! for (int i = 0; i < poolSize; i++) { ! executor.execute(new Worker(i));! } !

写一个Junit测试来验证: •  创建100对用户,初始balance均为0,允许负值 •  100个线程,每个线程执行1000次左右转账操作 •  5-10% 随机错误(引起补偿动作) •  检查最终结果(所有balance加起来应该为0)

Page 37: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

演示步骤 5

MacBook-­‐Pro-­‐13:compensatable  tjworks$  mvn  clean  test  -­‐Dtest=LoadTest  -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐    T  E  S  T  S  -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐  Running  com.mongoing.mongosaga.LoadTest  224  [main]  INFO  org.springframework.beans.factory.xml.XmlBeanDefini+onReader  -­‐  Loading  XML  bean  defini+ons  from  class  path  resource  [applica+onContext.xml]  …  …  ####  Time  used:  25s  ####  Total  compensa+ons:  6994  out  of  total  op:  99788    Results  :    Tests  run:  2,  Failures:  0,  Errors:  0,  Skipped:  0    !

运行测试

Page 38: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

演示步骤 6

>  db.accounts.aggregate({$group:{_id:"",  sum:  {$sum:  "$balance"}}})  {  "_id"  :  "",  "sum"  :  0  }  >  >  db.accounts.find().limit(10)  {  "_id"  :  ObjectId("57319bacc026280ce28867a3"),  "name"  :  "tj0",  "balance"  :  89000  }  {  "_id"  :  ObjectId("57319bacc026280ce28867a4"),  "name"  :  "mona0",  "balance"  :  -­‐89000  }  {  "_id"  :  ObjectId("57319bacc026280ce28867a5"),  "name"  :  "tj1",  "balance"  :  58000  }  {  "_id"  :  ObjectId("57319bacc026280ce28867a6"),  "name"  :  "mona1",  "balance"  :  -­‐58000  }  {  "_id"  :  ObjectId("57319bacc026280ce28867a7"),  "name"  :  "tj2",  "balance"  :  5000  }  {  "_id"  :  ObjectId("57319bacc026280ce28867a8"),  "name"  :  "mona2",  "balance"  :  -­‐5000  }  {  "_id"  :  ObjectId("57319bacc026280ce28867a9"),  "name"  :  "tj3",  "balance"  :  57000  }  {  "_id"  :  ObjectId("57319bacc026280ce28867aa"),  "name"  :  "mona3",  "balance"  :  -­‐57000  }  {  "_id"  :  ObjectId("57319bacc026280ce28867ab"),  "name"  :  "tj4",  "balance"  :  16000  }  {  "_id"  :  ObjectId("57319bacc026280ce28867ac"),  "name"  :  "mona4",  "balance"  :  -­‐16000  }  >    

验证结果

Page 39: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

简易测试结果 - MongoDB

SUB POINT

ATM 订单 跨行转账 电信扣费 . . .

测试场景

•  一台 Macbook Pro •  8G RAM •  4 Core •  100线程并发执行,每个线程执行1000次左右转账 •  MongoDB 3.2.0 运行于本机,无任何优化 •  Spring + MongoDB Java Driver

测试结果

•  每秒 3990 次转账操作,7%的模拟出错/补偿操作

•  结果100% 准确

•  相当于每天3.5亿次 – 银联支付每天7亿业务

Page 40: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

简易测试结果 - MySQL

SUB POINT

ATM 订单 跨行转账 电信扣费 . . .

测试场景

•  一台 Macbook Pro •  8G RAM •  4 Core •  100线程并发执行,每个线程执行1000次左右转账 •  MySQL 5.6 InnoDB •  Spring Transaction Management

测试结果

•  每秒 ~200 次转账操作

0  500  1000  1500  2000  2500  3000  3500  4000  4500  

Transfers/s  

MongoDB  

MySQL  

Page 41: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

事务补偿设计

SUB POINT

ATM 订单 跨行转账 电信扣费 . . .

SUB POINT

注意事项 •  补偿!=回滚

•  回滚: 动作从未被提交过 •  补偿: 通过提交另一个操作来中和

前一个动作的效果

•  不是所有场景都适合事务补偿,如多进程同时更新一条记录,并且不是增加或减少的情况

•  尽量实现幂等性:失败时可以自动重试(功能正在实现中)

ATM 订单 跨行转账 电信扣费 . . .

场景举例:

订单处理

转账类业务

电信扣费

ERP进销存

. . .

Page 42: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

补充说明

SUB POINT

ATM 订单 跨行转账 电信扣费 . . .

SUB POINT

注意事项 •  补偿!=回滚

•  回滚: 动作从未被提交过 •  补偿: 通过提交另一个操作来中和

前一个动作的效果

•  不是所有场景都适合事务补偿,如多进程同时更新一条记录,并且不是增加或减少的情况

•  尽量实现幂等性:失败时可以自动重试(功能正在实现中)

ATM 订单 跨行转账 电信扣费 . . .

关于mongosaga的使用,此PPT内所含信息不是最新的。 具体使用请参见github页面。 订单处理

电信扣费 https://github.com/tjworks/mongosaga

ERP进销存

. . .

Page 43: 在 ongoDB 中实现强事务 - · PDF file分布式事务数据库 ! 二阶段提交 1. 基于锁机制,提交阶段用到资源都处于阻塞状态 2. TransactionManager 单点故障

MongoDB 官网 http://www.mognodb.com MongoDB 中文社区 http://www.mongoing.com