seata连oracle,完美起航

不了解分布式事务的 看上篇文章点击这里

Seata集成实战

Seata须知

下面进入实战,环境: springBoot2.2.2 + springCloud Hoxton.SR1 + seata1.2.0 + Mysql5.7

首先我们要明白seata中的几个术语:

3e03f87eedfdbff8c5249f2785157f97.png

我们来想象一个场景,现在有一个微服务架构的电商系统,其中包含了订单服务、库存服务

他们分别部署在不同的服务器上,连接的也是不同的数据库。(以下的操作不考虑复杂情况)

现在用户对商品进行购买操作,我们要做两件事:

1.调用订单服务====> 针对用户下单的商品进行订单生成入库

2.调用库存服务====> 针对该商品进行库存削减

我们可以想到,订单项目和库存项目 每一个都是RM(资源管理器)

因为他们驱动着自己本地的分支事务提交或者回滚

如图:

5ad81a25ee21e07bedbc82914b494061.png

·

那么TM是谁?

如果我们还有一个服务 用来专门处理业务,这个服务中会调用 订单服务,库存服务。那么他就应该是TM

因为这个业务服务,需要开始全局事务。

59e72ba062a6d7ef57982f9afcf3d787.png

那么谁又是TC(事务协调者)

其实就是Seata服务。那么一会我们会开启seata服务。他就是TC

Seata与SpringBoot、Cloud集成

1. 下载seata1.2.0

c07825bc308e0aab7155a72de4ae0090.png

2. 创建数据库

这里注意:我们需要创建什么 这里的sql我会在后边粘贴,现在只需要知道创建什么即可。

a.创建单独的数据库(数据库名随意),用来记录分支信息等等

06441d8860c1759ec18acfa7fa5b3cf5.png

b.在每个业务数据库中都要创建undo_log表(用于记录回滚操作的)

如图:订单服务连接distribute_order数据库,则需要创建一张undo_log , 库存服务连接的是distribute_store 也是如此

35ec74848ba5cf18e09aa02b298dd3db.png

编写order订单服务,store库存服务

编写过程略,我们只需要知道对数据库进行了什么操作即可

订单服务:连接distribute_order库,会插入一条记录进order表。

库存服务:连接distribute_store库,会根据购买的商品id,针对商品进行库存削减。

这里只贴出关键代码:

订单服务:

insert into `order`(onum) values (#{onum})

库存服务:

update good set count = count - 1 where id = #{id}

3.进入到重要环节: 修改seata-server的配置

3.1找到registry.conf并修改

7db1298e29e22224c8e5c3fa5eea5016.png

我们都知道微服务是有注册中心的(注册中心不懂说明不会微服务…),我们现在需要把seata服务注册到中心中

注册中心我用的是eureka,如图

dd1116c036a85c913abb0a6efc6448df.png

所以我们修改registry.conf 主要就是type=“eureka” , 以及eureka的地址别写错了。

registry {

# file 、nacos 、eureka、redis、zk、consul、etcd3、sofa

type = "eureka"

nacos {

application = "seata-server"

serverAddr = "localhost"

namespace = ""

cluster = "default"

username = ""

password = ""

}

eureka {

serviceUrl = "http://localhost:8761/eureka/"

application = "seata-server"

weight = "1"

}

}

config {

# file、nacos 、apollo、zk、consul、etcd3

type = "file"

file {

name = "file.conf"

}

}

3.2 修改file.conf

这个文件主要是配置seata-server连接的数据库,还记得我们在第二步创建的数据库吗

这里主要就是配置service模块 、和下面的db模块

#这里手动加入service模块

service {

#transaction service group mapping

#修改,可不改,my_test_tx_group随便起名字。

vgroup_mapping.my_test_tx_group = "default"

#only support when registry.type=file, please don't set multiple addresses

# 此服务的地址

default.grouplist = "127.0.0.1:8091"

#disable seata

disableGlobalTransaction = false

}

## transaction log store, only used in seata-server

store {

## store mode: file、db

mode = "db"

## 数据库连接的位置 重要

db {

## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) etc.

datasource = "druid"

## mysql/oracle/postgresql/h2/oceanbase etc.

dbType = "mysql"

driverClassName = "com.mysql.jdbc.Driver"

url = "jdbc:mysql://localhost:3306/seata"

user = "root"

password = "mysql"

minConn = 5

maxConn = 30

globalTable = "global_table"

branchTable = "branch_table"

lockTable = "lock_table"

queryLimit = 100

maxWait = 5000

}

}

4.修改项目文件集成seata功能

这一步主要是让我们的order服务,store服务、以及我们的业务服务。能够使用分布式事务

4.1修改pom文件 加入seata依赖

只要涉及分布式事务的项目,都加上 ! !

com.alibaba.cloud

spring-cloud-starter-alibaba-seata

2.2.1.RELEASE

4.2修改项目配置文件

这里大家可以修改properties文件/yml配置文件。加入以下的配置,当然yml和properties写法有些区别这里不多赘述。大家都懂

##############################[seata配置]###################################################

#是否使用分布式事物

seata:

enabled: true

application-id: seata-bus

tx-service-group: my_test_tx_group

enable-auto-data-source-proxy: true

service:

vgroup-mapping.my_test_tx_group: default

grouplist.default: localhost:8091

##############################[seata配置]###################################################

5.使用注解@GlobalTransactional开启分布式事务

这里调用了库存服务,又调用了订单服务

这是service业务层:

@GlobalTransactional

public String testGlobalTx(){

System.out.println("事务XID="+RootContext.getXID());

String url2 = "http://seata-store/update?id=1";

String result2 = restTemplate.getForObject(url2, String.class);

//如何消费provider的服务,重点问题

String url = "http://seata-order/insert?onum=shaoshuai";

String result = restTemplate.getForObject(url, String.class);

System.out.println("seata=============开始全局事务~~~");

return result;

}

顺便编写下controller

@RestController

public class TestController {

@Autowired

TestService tv;

@RequestMapping("/globalTx")

public String select() {

return tv.testGlobalTx();

}

}

测试结果

我们先看下整体的项目结构

33a289a9eaac9bf29403211b70909cce.png

1.测试事务能否正确回滚(Rollback)

3.1 开启所有项目

eureka-server(注册中心),开启springcloud-seata(业务服务)、springcloud-order(订单服务)、springcloud-store(库存服务)

fcdb307b76f628f77996401f80b7c38d.png

3.2 开启seata服务器

找到seata/bin目录下的seata-server.bat 开启

b3953952d6cf9ece3518133b4c7a3b99.png

3.3 在订单接口里制造错误

![在这里插入图片描述](https://img-blog.csdnimg.cn/20201223143933976.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMzNzM5MjMw,size_16,color_FFFFFF,t_70)

3.4 测试接口

我们刚才在订单接口中制造一个错误,是为了观察整个事务是否能正确回滚

如果库存依旧减少: 事务没有正确回滚。

库存没有减少: 事务可能回滚 / 事务没有执行 (我们需要观察seata的日志)

先来看一下数据库中的数据情况 订单表

f24f088577f29840c30ee65b0467f364.png

库存表 300个

ad16f4d811ef98ac67bf3ef8bf2df998.png

测试接口访问

http://localhost:10005/globalTx

aa61353bc325754f316770b3d0c6708e.png

报错了,没错 by / zero就是我们订单服务的错误

我们观察store服务执行了没,看日志

98c98684118718693bd477d1fd0552dc.png

其实是执行了的,我们再看数据库库存是否削减

1227ba896a859b811c6ed8cd62857927.png

没有削减,那么究竟是事务根本就没有生效 还是 事务已经生效了呢,我们观察seata服务器日志

0559c31eb5f1f11945591605b44eae5e.png

其实已经rollback了,所以是没问题的。

到这文章就已经结束了。接下来是成功测试环节。

1.测试事务能否正确提交(Commit)

接下来把订单接口的错误取消,试试。

814fdcdcc5da3914471a3bce9430f15b.png

访问接口:

http://localhost:10005/globalTx

0af25b62c1a2c1f4e39747d73f3009b2.png

看数据库

9ea906218285e6c6c05715f0626f5caa.png

6cec10664c68919a0ebf22183a3ff14f.png

再看seata日志

ae3cbd9df59a0f79b1703ef096df8435.png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值