Distributed transactions have the following solutions:
- XA
- TCC
- Seata framework
- AT transaction
- SAGA
- Reliable message final consistency
- Best effort notification
Seata
Seata is an open source one-stop distributed transaction solution, which is committed to providing high-performance and easy-to-use distributed transaction services. Seata will provide users with AT, TCC, SAGA and XA transaction modes to create a one-stop distributed solution for users.
Seata AT
Seata's AT mode (Automatic Transaction) is a non intrusive distributed transaction solution
Link 1: Specific working mechanism of Seata AT
TC (Transaction Coordinator)
Because each service cannot perceive whether the transaction is successful or not, a special service is needed to coordinate the running state of each service.
TM (Transaction Manager) applies to TC to start a global transaction
RM (Resource Manager), RM is responsible for managing branch transactions (i.e. local transactions of microservices)
Link 2: Add AT distributed transaction to Spring Cloud microservice
Seata Server is TC, which can be downloaded and started directly from the official warehouse. Download address: https://github.com/seata/seata/releases
Reduce the pressure on TC. There is no cluster. You can only create several more transaction groups to manage several modules
Seata Server configuration
If the computer memory is insufficient, set the memory in seata-server.bat to 256M
%JAVACMD% %JAVA_OPTS% -server -Xmx2048m -Xms2048m -Xmn1024m -Xss512k -XX:Sur......
There are two profiles for Seata Server:
- seata/conf/registry.conf
- seata/conf/file.conf
registry.conf
registrv.conf -- register with the registry
registry { # file ,nacos ,eureka,redis,zk,consul,etcd3,sofa # Select eureka registration configuration here type = "eureka" nacos { ...... } # Registration configuration of eureka eureka { # Address of Registration Center serviceUrl = "http://localhost:8761/eureka" # Register the name and service ID with the registry. The default is default application = "seata-server" weight = "1" } redis { ...... } ......
registry { # file ,nacos ,eureka,redis,zk,consul,etcd3,sofa type = "eureka" nacos { serverAddr = "localhost" namespace = "" cluster = "default" } eureka { serviceUrl = "http://localhost:8761/eureka" # application = "default" # weight = "1" } redis { serverAddr = "localhost:6379" db = "0" password = "" cluster = "default" timeout = "0" } zk { cluster = "default" serverAddr = "127.0.0.1:2181" session.timeout = 6000 connect.timeout = 2000 username = "" password = "" } consul { cluster = "default" serverAddr = "127.0.0.1:8500" } etcd3 { cluster = "default" serverAddr = "http://localhost:2379" } sofa { serverAddr = "127.0.0.1:9603" application = "default" region = "DEFAULT_ZONE" datacenter = "DefaultDataCenter" cluster = "default" group = "SEATA_GROUP" addressWaitTime = "3000" } file { name = "file.conf" } } config { # file,nacos ,apollo,zk,consul,etcd3,springCloudConfig type = "file" nacos { serverAddr = "localhost" namespace = "" group = "SEATA_GROUP" } consul { serverAddr = "127.0.0.1:8500" } apollo { app.id = "seata-server" apollo.meta = "http://192.168.1.204:8801" namespace = "application" } zk { serverAddr = "127.0.0.1:2181" session.timeout = 6000 connect.timeout = 2000 username = "" password = "" } etcd3 { serverAddr = "http://localhost:2379" } file { name = "file.conf" } }
file.conf
file.conf – the transaction coordinator used by the transaction group
Configure the eureka registry, the connection address of eureka service and the registered service name in the registry.conf file
Specify file.conf -- log in the library during the operation of Seata server
config { # file,nacos ,apollo,zk,consul,etcd3 # Here, select use local file to save the configuration type = "file" ...... etcd3 { serverAddr = "http://localhost:2379" } file { # Use the local file to set the file name of the configuration file here name = "file.conf" } }
store { ## store mode: file,db,redis # Select database storage here mode = "db" ## file store property file { ...... } # Database storage db { ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp)/HikariDataSource(hikari) etc. datasource = "druid" ## mysql/oracle/postgresql/h2/oceanbase etc. dbType = "mysql" driverClassName = "com.mysql.jdbc.Driver" # Database connection configuration url = "jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8" user = "root" password = "root" minConn = 5 maxConn = 30 # Transaction log table name setting globalTable = "global_table" branchTable = "branch_table" lockTable = "lock_table" queryLimit = 100 maxWait = 5000 } ## redis store property redis { ...... } }
transport { # tcp udt unix-domain-socket type = "TCP" #NIO NATIVE server = "NIO" #enable heartbeat heartbeat = true # the client batch send request enable enableClientBatchSendRequest = true #thread factory for netty threadFactory { bossThreadPrefix = "NettyBoss" workerThreadPrefix = "NettyServerNIOWorker" serverExecutorThread-prefix = "NettyServerBizHandler" shareBossWorker = false clientSelectorThreadPrefix = "NettyClientSelector" clientSelectorThreadSize = 1 clientWorkerThreadPrefix = "NettyClientWorkerThread" # netty boss thread size,will not be used for UDT bossThreadSize = 1 #auto default pin or 8 workerThreadSize = "default" } shutdown { # when destroy server, wait seconds wait = 3 } serialization = "seata" compressor = "none" } service { #transaction service group mapping # order_ tx_ Group is consistent with the configuration of "TX service group: order_tx_group" in yml # "Seata server" is consistent with the registered name of TC server # Get the address of Seata server from eureka, register yourself with Seata server, and set group vgroupMapping.order_tx_group = "seata-server" #only support when registry.type=file, please don't set multiple addresses order_tx_group.grouplist = "127.0.0.1:8091" #degrade, current not support enableDegrade = false #disable seata disableGlobalTransaction = false } client { rm { asyncCommitBufferLimit = 10000 lock { retryInterval = 10 retryTimes = 30 retryPolicyBranchRollbackOnConflict = true } reportRetryCount = 5 tableMetaCheckEnable = false reportSuccessEnable = false } tm { commitRetryCount = 5 rollbackRetryCount = 5 } undo { dataValidation = true logSerialization = "jackson" logTable = "undo_log" } log { exceptionRate = 100 } }
Start: double click the seata/bin/seata-server.bat file
Or CMD: seata-server.bat in the current directory
Error reporting: path, home environment
bat is not supported in the new version of jdk
Add AT transaction in business module configuration
file.conf
Which coordinator to use
service{ VgroupMapping.Transaction group name="Registry coordinator name" } perhaps service{ VgroupMapping.group="Transaction group name" VgroupMapping.tv="Registry coordinator name" }
application.yml
application.yml – transaction group naming
Just write one transaction group for multiple modules
spring: ...... cloud: alibaba: seata: tx-service-group: order_tx_group datasource: url: jdbc:mysql:/l/seata_order?useUnicode=true&driver-class-name: com.mysql.cj.jdbc.Driveruser name: root password: root jdbcUrl: ${spring. datasource.url} ......
On the business method, add annotations
@GlobalTransactional -- used to start global transactions, added only in the first module (method).
@Transactional -- control local transactions
Dependency:
<seata.version>1.3.0</seata.version> <spring-cloud-alibaba-seata.version>2.0.0.RELEASE</spring-cloud-alibaba-seata.version> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-seata</artifactId> <version>${spring-cloud-alibaba-seata.version}</version> <exclusions> <exclusion> <artifactId>seata-all</artifactId> <groupId>io.seata</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>io.seata</groupId> <artifactId>seata-all</artifactId> <version>${seata.version}</version> </dependency>
Error: either not configured or not configured correctly
Write your own data source configuration
By creating the data source proxy object dataSourceProxy
Configuration class
import com.alibaba.druid.pool.DruidDataSource; import com.zaxxer.hikari.HikariDataSource; import io.seata.rm.datasource.DataSourceProxy; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import javax.sql.DataSource; /* The custom data source auto configuration class conflicts with the default data source auto configuration class in spring, You need to exclude the default automatic configuration of spring in the startup class */ @Configuration public class DSAutoConfiguration { // Create original data source object /*hikari The database address parameter used is not url, but JDBC url spring datasource: url: jdbc:mysql:/l/seata_order?useUnicode=true&driver-class-name: com.mysql.cj.jdbc.Driverusername: root password: root jdbcUrl: ${spring. datasource.url} */ // @ConfigurationProperties injects the configured parameters (spring.datasource in yml) into the HikariDataSource object @ConfigurationProperties(prefix = "spring.datasource") @Bean public DataSource dataSource() { return new HikariDataSource(); // return new DruidDataSource(); } // Create a data source proxy object because two objects of the same type are created here. spring does not know who to choose. First, add an object annotation @Primary // Preferred object @Bean public DataSource dataSourceProxy(DataSource ds) { //DataSource is the target object of the proxy return new DataSourceProxy(ds); }
In startup class:
Because it is written directly, spring's own default configuration class is excluded
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
yml
Phase II submission
If you fail
Delete log, rollback