BeetlSQL 3.2.0 发布,多库和微服务事务支持

本次发布主提供多库和微服务事务支持,使用了 BeetlSQL 的自带的 Saga 实现

新增多库和微服务 Saga 实现 修复代码生成因为重构带来的问题 Saga文档

Maven

1<dependency> 2 <groupId>com.ibeetl</groupId> 3 <artifactId>beetlsql</artifactId> 4 <version>3.2.0-RELEASE</version> 5</dependency>

Saga 初期是长事务的解决方案,微服务流行后也可以为微服务提供事务解决方案。不同于传统的数据库事务或者 2 阶段提交,必须·依赖于数据库系统实现 ACID 事务,Saga 不依赖于特定系统(实际上也不可能让所有系统实现 ACID,比如 Redis,Mongdb),只要求特定系统能提供补偿操作,在出错的时候能执行补偿操作即可。因此可以很方便用在现代的微服务架构中。

一个长事务的例子,如订购电影票,分为选座位和支付俩个步骤。用户可能会花好几分钟才能能完成。另一个例子是下单旅游产品,需要酒店,飞机,旅行社各个系统协作。 关于Saga,我认为最好的文章是 https://docs.microsoft.com/en-us/azure/architecture/reference-architectures/saga/saga,因为他即告诉你什么是Saga。也告诉你Saga不完美的地方。

因此 Saga 的核心是补偿操作以及执行这些操作的任务的管理。下面列举了一些目前我认为的现在一些 Saga 框架实现的缺点

补偿操作需要手动编写,这工作量不小,而且容易写错,需要仔细审核代码 有些框架能自动根据 SQL 产生逆向 SQL,这有效减少了编写补偿的工作。但解析 SQL 和生成逆向 SQL 的难度非常大,会成为 Saga 框架的主要难点 现在几乎所有的 Saga 框架将要改变编写微服务调用方式,因为 Saga 提倡通过消息调用来实现服务调用和补偿操作。不符合编写业务代码习惯,还是期望能在编写微服务的时候,像传统事务编程模式那样,微服务业务代码嵌套在一个 Saga 事务开始,提交或者回滚即可 几乎所有的框架都要实现进行 Saga 编排,即 Saga 事务里那些微服务调用必须事先编排(配置)。这非常不灵活,因为业务时刻在变化。非常有可能升级了业务代码,却忘记重新编码。 程序员期望能像普通编写业务代码那样而不需要实现编排配置 BeetlSQL 的 Saga 实现试图解决上述问题。让微服务编程变得跟简单。

单系统多库 Saga 事务

1@Test 2public void simple(){ 3 SagaContext sagaContext = SagaContext.sagaContextFactory.current(); 4 UserMapper userMapper = sqlManager.getMapper(UserMapper.class); 5 long count = sqlManager.allCount(User.class); 6 try{ 7 sagaContext.start() 8 9 User user = new User(); 10 user.setName("abc"); 11 userMapper.insert(user); 12 //根据名字hash入不同数据库 13 User user2 = new User(); 14 user2.setName("efg"); 15 userMapper.insert(user2); 16 if(1==1){ 17 throw new RuntimeException("模拟异常"); 18 } 19 sagaContext.commit(); 20 21 }catch(RuntimeException ex){ 22 sagaContext.rollback(); 23 } 24 long afterCount = sqlManager.allCount(User.class); 25 Assert.assertEquals(count,afterCount); 26}

微服务Saga事务,采用同样的编程方式

1SagaContext sagaContext = SagaContext.sagaContextFactory.current(); 2try { 3 sagaContext.start(gid); 4 //模拟调用俩个微服务,订单和用户 5 rest.postForEntity(orderAddUrl, null,String.class, paras); 6 rest.postForEntity(userBalanceUpdateUrl, null,String.class, paras); 7 if (1 == 1) { 8 throw new RuntimeException("模拟失败,查询saga-server 看效果"); 9 } 10} catch (Exception e) { 11 sagaContext.rollback(); 12 return e.getMessage(); 13}

BeetlSQL 的目标是提供开发高效,维护高效,运行高效的数据库访问框架,在一个系统多个库的情况下,提供一致的编写代码方式。支持如下数据平台

  • 传统数据库:MySQL,MariaDB,Oralce,Postgres,DB2,SQL Server,H2,SQLite,Derby,神通,达梦,华为高斯,人大金仓,PolarDB 等
  • 大数据:HBase,ClickHouse,Cassandar,Hive
  • 物联网时序数据库:Machbase,TD-Engine,IotDB
  • SQL查询引擎:Drill,Presto,Druid
  • 内存数据库:ignite,CouchBase
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )