1、事务
访问并可能更新数据库中数据库中各种数据线的一个程序执行单元
原子性:事务是一个不可分割的工作单位,一个事务要么都做要么都不做
一致性:必须是使数据库从一个一致性到另一个一致性的状态,中间状态不能被观察到
隔离性:一个事务的执行不能被其他事务干扰
持久性:一个事务一旦提交,对数据库中的数据的改变是永久的
2、本地事务
@Transational
大多数场景下,我们的应用都只需要操作单一的数据库,称为本地事务
3、常见分布式事务解决方案
都是“两阶段(2Pc)”,两阶段是指完成整个分布式事务,划分为两个步骤
这四种常见的解决方案,分别对应分布式的四种模式:AT、TCC、Saga、XA
Seata是一款开源的分布式事务解决方案,提供高性能和简单已用的分布式事务服务。Seata将用户提供了AT、TCC、SAGA和XA事务模式,为用户打造一站式解决方案。
官网:http://seata.io/zh-cn/index.html
源码:https://github.com/seata/seata
维护全局和分支事务的状态,驱动全局事务提交或回滚
定义全局事务的范围:开始全局事务提交或回滚全局事务
管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚
三阶段提交协议3PC难实现,主流还是2PC协议。
2PC两阶段提交(Prepare和Commit)
遇到的问题:
同步阻塞:参与者在等待协调者的指令时,其实实在等待其他参与者的响应,此过程中,参与者是无法进行其他操作的,也就是阻塞了运行,如果存在网络异常等原因会一直阻塞下去
单点:在2PC中,一切请求都来自协调者,所以协调者的地位是至关重要的,如果协调者宕机,参与者会一直阻塞并且占用事务资源。如果协调者也是分布式,使用选主方式提供服务,俺么在一个协调者挂掉后,可以获取另一个协调者继续后续的服务。但是新的协调者无法知道上一个事务的全部状态信息,所以无法顺序处理上一个事务
数据不一致:commit事务过程中commit请求和rollback请求可能因为协调者宕机成协调者与参与者网络问题丢失,导致部门参与者没有收到请求,而其他参与者已经执行了,导致数据不一致
环境可靠性依赖:协调者prepare请求发出后,等待响应,如果有参与者宕机或网络中断,都会导致协调者无法收到所有参与者的响应,那么2PC中,协调者会等到一定时间,超时后触发事务中断,这个过程中,协调者和其他参与者都是阻塞。
无侵入的分布式事务解决方案
需要用户根据自己的业务场景实现try、confirm和cancel三个操作。事务发起方在一阶段执行try方式,在二阶段提交执行confirm方法,二阶段回滚执行cancel方法。
Seata分TC、TM和RM三个角色,TC(Server端)为单独服务端部署,TM和RM(Client端)由业务系统集成。
Server端存储模式(store.mode)现有file、db、redis三种(后续将引入raft,mongodb)
在seata官网的下载页面,可以查询到对应支持的springboot版本号
这里使用的是springboot2.7.13,seata对应版本1.5.2,win上配置,DB+NOCOS
下载后解压缩
启动包: seata-->conf-->application.yml,修改store.mode="db或者redis"
启动包: seata-->conf-->application.example.yml中附带额外配置,将其db|redis相关配置复制至application.yml,进行修改store.db或store.redis相关属性。
server:
port: 7091spring:
application:
name: seata-serverlogging:
config: classpath:logback-spring.xml
file:
path: ${user.home}/logs/seata
extend:
logstash-appender:
destination: 127.0.0.1:4560
kafka-appender:
bootstrap-servers: 127.0.0.1:9092
topic: logback_to_logstashconsole:
user:
username: seata
password: seataseata:
config:
type: nacos
nacos:
server-addr: 127.0.0.1:8848
namespace:
group: SEATA_GROUP
username: nacos
password: nacos
data-id: seataServer.yml
registry:
type: nacos
nacos:
application: seata-server
server-addr: 127.0.0.1:8848
group: SEATA_GROUP
namespace:
cluster: default
username: nacos
password: nacos
store:
mode: db
db:
datasource: druid
db-type: mysql
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/seata_server?rewriteBatchedStatements=true
user: root
password: root
min-conn: 5
max-conn: 100
global-table: global_table
branch-table: branch_table
lock-table: lock_table
distributed-lock-table: distributed_lock
query-limit: 100
max-wait: 5000
security:
secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017
tokenValidityInMilliseconds: 1800000
ignore:
urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/api/v1/auth/login
全局事务会话信息由3块内容构成
全局事务 | global_table |
分支事务 | branch_table |
全局锁 | lock_table |
\seata-server-1.5.2\seata\script\config-center\config.txt
其他的例如数据库、redis根据自己的配置更改
本地登录:http://localhost:8848/nacos
# 注意:配置事务=配置事务分组名称default
# Seata 事务分组
service.vgroupMapping.default_tx_group=default
# 本地127.0.0.1可以直接运行
\seata-server-1.5.2\seata\script\config-center\nacos\nacos-config.sh
# 远程服务端
sh ${SEATAPATH}/script/config-center/nacos/nacos-config.sh -h localhost -p 8848 -g SEATA_GROUP -T 5a3c7d6c-f497-4d68-a71a-2e5e3340b3ca
本地win直接运行
seata-server-1.5.2\seata\bin\seata-server.bat
如果是远端服务器
seata-server.sh -h 127.0.0.1 -p 8091 -m db -n 1 -e test
参数 | 全写 | 作用 | 备注 |
-h | --host | 指定在注册中心注册的IP | 不指定获取当前的IP,外部访问不熟在云环境和容器中的sevrer建议指定 |
-p | --port | 指定server启动的端口 |
默认8091 |
-m | --storeMode | 事务日志存储方式 | 支持file\db\redis,默认file (Seata-Server 1.3及以上版本支持redis) |
-n | --serverNode | 只用seata-server的节点ID | 默认1 |
-e | --seataEnv | 指定seata-server运行环境 | 参考 http://seata.io/en-us/docs/ops/multi-configuration-isolation.html |