事务(Transaction),一般是指要做的或做的事情。术语中指访问并可能更新数据库中各个数据项的一个程序执行单元。事务通常由高级数据库操作语言或编程语言书写的用户程序所引起,并用形如 begin transaction 或 end transaction 语句(或函数调用)来界定。事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全体操作组成。
CAP 理论:CAP 理论由计算机科学家 Eric Brewer 在 2000 年提出,后来被广泛接受并成为分布式系统设计中的重要指导原则。分布式系统中的基本定理,指出在一个分布式数据存储系统中,无法同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition Tolerance)这三个特性。
BASE 理论:一种相对 CAP 理论的分布式系统设计理论,提出一种弱一致性的替代方案,用于满足分布式系统的高可用性需求。核心思想是弱化强一致性的要求,以提高系统的可用性和性能。BASE 适用于那些不需要强一致性、但需要高响应速度和高可用性的分布式系统,比如电商平台和社交媒体等。
$ docker run -d -p 3306:3306 --name seata -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7 $ docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0fb9c8e50a82 mysql:5.7 "docker-entrypoint.s…" 50 seconds ago Up 49 seconds 0.0.0.0:3306->3306/tcp, 33060/tcp seata
$ docker exec -it seata mysql -uroot -p123456 mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.7.44 MySQL Community Server (GPL)
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> CREATE DATABASE `order`; Query OK, 1 row affected (0.00 sec) mysql> CREATE DATABASE stock; Query OK, 1 row affected (0.00 sec) mysql> CREATE DATABASE account; Query OK, 1 row affected (0.00 sec) mysql> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | account | | mysql | | order | | performance_schema | | stock | | sys | +--------------------+ 7 rows in set (0.00 sec)
$ sh seata-server.sh -p 8091 -h 127.0.0.1 -m file apm-skywalking not enabled seata-server is starting, you can check the /d/projects/seata/seata-server-1.5.2/seata/logs/start.out
16:33:03.227 INFO --- [ main] io.seata.server.ServerApplication : Starting ServerApplication v1.5.2 using Java 1.8.0_202 on LAPTOP-CJVNN4P6 with PID 12296 (D:\projects\seata\seata-server-1.5.2\seata\target\seata-server.jar started by solisamicus in D:\projects\seata\seata-server-1.5.2\seata\bin) 16:33:03.232 INFO --- [ main] io.seata.server.ServerApplication : No active profile set, falling back to default profiles: default 16:33:04.876 INFO --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 7091 (http) 16:33:04.885 INFO --- [ main] o.a.coyote.http11.Http11NioProtocol : Initializing ProtocolHandler ["http-nio-7091"] 16:33:04.886 INFO --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 16:33:04.886 INFO --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.55] 16:33:04.948 INFO --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 16:33:04.948 INFO --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1659 ms 16:33:05.441 INFO --- [ main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html] 16:33:05.597 INFO --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure Ant [pattern='/'] with [] 16:33:05.597 INFO --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure Ant [pattern='/**/*.css'] with [] 16:33:05.597 INFO --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure Ant [pattern='/**/*.js'] with [] 16:33:05.597 INFO --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure Ant [pattern='/**/*.html'] with [] 16:33:05.597 INFO --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure Ant [pattern='/**/*.map'] with [] 16:33:05.597 INFO --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure Ant [pattern='/**/*.svg'] with [] 16:33:05.598 INFO --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure Ant [pattern='/**/*.png'] with [] 16:33:05.598 INFO --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure Ant [pattern='/**/*.ico'] with [] 16:33:05.598 INFO --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure Ant [pattern='/console-fe/public/**'] with [] 16:33:05.598 INFO --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure Ant [pattern='/api/v1/auth/login'] with [] 16:33:05.615 INFO --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@594d9f07, org.springframework.security.web.context.SecurityContextPersistenceFilter@118dcbbd, org.springframework.security.web.header.HeaderWriterFilter@2e26173, org.springframework.security.web.authentication.logout.LogoutFilter@2ecf5915, io.seata.console.filter.JwtAuthenticationTokenFilter@5befbac1, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@350ec690, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@34a2d6e0, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@5e9f73b, org.springframework.security.web.session.SessionManagementFilter@203d1d93, org.springframework.security.web.access.ExceptionTranslationFilter@2f74900b, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@3c6c4689] 16:33:05.639 INFO --- [ main] o.a.coyote.http11.Http11NioProtocol : Starting ProtocolHandler ["http-nio-7091"] 16:33:05.660 INFO --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 7091 (http) with context path '' 16:33:05.670 INFO --- [ main] io.seata.server.ServerApplication : Started ServerApplication in 3.177 seconds (JVM running for 3.761) 16:33:07.372 INFO --- [ main] i.s.core.rpc.netty.NettyServerBootstrap : Server started, service listen port: 8091 16:33:07.384 INFO --- [ main] io.seata.server.ServerRunner : seata server started in 1713 millSeconds
运行示例
依次启动
DubboStockServiceStarter:初始化库存数据(添加库存记录)。
DubboAccountServiceStarter:初始化账户数据(添加用户账户记录)。
DubboOrderServiceStarter:启动订单服务(等待下单操作)。
DubboBusinessTester:执行测试场景(下单操作,触发分布式事务)。
$\text {DubboAccountServiceStarter.java}$:
启动账户服务。
初始化账户表数据:
删除用户 U100001 的账户记录(若存在)。
插入一条新记录,给用户 U100001 分配初始余额 999。
1 2
accountJdbcTemplate.update("delete from account_tbl where user_id = 'U100001'"); accountJdbcTemplate.update("insert into account_tbl(user_id, money) values ('U100001', 999)");
1 2 3 4 5 6 7
mysql> SELECT * FROM `account`.`account_tbl`; +----+---------+-------+ | id | user_id | money | +----+---------+-------+ | 1 | U100001 | 999 | +----+---------+-------+ 1 row in set (0.00 sec)
mysql> SELECT * FROM `order`.`order_tbl`; Empty set (0.00 sec)
$\text {DubboStockServiceStarter.java}$:
启动库存服务。
初始化库存表数据:
删除商品 C00321 的库存记录(若存在)。
为商品 C00321 添加库存 100。
1 2
stockJdbcTemplate.update("delete from stock_tbl where commodity_code = 'C00321'"); stockJdbcTemplate.update("insert into stock_tbl(commodity_code, count) values ('C00321', 100)");
1 2 3 4 5 6 7
mysql> SELECT * FROM `stock`.`stock_tbl`; +----+----------------+-------+ | id | commodity_code | count | +----+----------------+-------+ | 1 | C00321 | 100 | +----+----------------+-------+ 1 row in set (0.00 sec)