Seat
What is Seata?
Seata is an easy-to-use, high-performance, open source distributed transaction solution.
Seata is an easy-to-use, high-performance, open source distributed transaction solution.
AT mode
AT
The pattern is a non-intrusive distributed transaction solution. In the AT
mode, the user can focus on their "business SQL
"
users "business SQL
" is to stage a global transaction, Seata
the framework will automatically generate a two-stage transaction commit and rollback operations.
AT
How does the model do not invade the business:
-
Stage:
a stage,Seata
intercepts, "businessSQL
", the first parsingSQL
semantics, find the "businessSQL
" to update business data,
before business data is updated, save it tobefore image
, and then perform a "businessSQL
" update business data in business After the data is updated,
save it againafter image
, and finally generate a row lock. The above operations are all completed within a database transaction, which ensures the atomicity of one-stage operations. -
Two-phase commit protocol:
two-stage if it is to submit the case, because "businessSQL
" at a stage has been submitted to the database, theSeata
snapshot data and row lock frame just to save a stage deleted, you can complete the data clean-up. -
Two-stage rollback:
If the second stage is a rollback,Seata
you need to roll back the "businessSQL
" that has been executed in the first stage to restore the business data.
The rollback method is tobefore image
restore business data; but before restoring, you must first check dirty writes, compare "database current business data" andafter image
,
if the two data are exactly the same, it means that there is no dirty write, you can restore business data, if inconsistent It means that there is dirty writing, and it needs to be manually processed.
AT
A phase mode, two-phase commit and rollback by Seata
frame automatically generated, users only need to write a "business SQL
", will be able to easily access the distributed transaction AT
model is a distributed transaction without any invasive solutions for business.
(The above is selected from 4 modes of distributed transactions in Zhihu )
nacos-dubbo
nacos-dubbo
It is a simple Seata AT
model entry project, used dubbo
to realize the call between services.
Description
provider
There are only two types of projects in the project, one is api
, the other is the service
so-called api
project is that the project has only interfaces and domain
no implementation. This project will be dependent on api
the implementation ( service
) and service
the project that needs to be called .
service
A project is a api
project to implement a project, which is generally a project to operate a database or other business.
consumer
There are only two types of projects. One is api
, and the other is. As service
above, the service
project will call the corresponding provider
interface and use dubbo rpc
the communication
business
Project refers to the business layer code that project, he will go to depend on consumer
the api
project. Then to the externally provided RESTFul
interface
So in this project, to start two provider
in service
, and then start consumer
the service
finally start business
the project.
ready
First, you need to create two libraries, one inventory release order
table and one inventory release order_item
.
CREATE TABLE tb_order (
id BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
order_id BIGINT(20) NOT NULL,
user_id BIGINT(20) NOT NULL);
CREATE TABLE tb_order_item (
id BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT(20) NOT NULL,
order_id BIGINT(20) NOT NULL,
order_item_id BIGINT(20) NOT NULL);
In addition, you also need to create one in each libraryundo_log
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`branch_id` bigint(20) NOT NULL,
`xid` varchar(100) NOT NULL,
`context` varchar(128) NOT NULL,
`rollback_info` longblob NOT NULL,
`log_status` int(11) NOT NULL,
`log_created` datetime NOT NULL,
`log_modified` datetime NOT NULL,
`ext` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
provider
The main increases Seata
dependence
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
Configuration file
spring
alibaba:
seata:
# 自定义事务组名称 tx_group,需要与服务端一致
tx-service-group: tx_group
Configuration class, depending on the projectSeataConfiguration
import io.seata.rm.datasource.DataSourceProxy;
@Configuration
public class SeataConfiguration {
@Primary
@Bean("dataSource")
public DataSourceProxy dataSource(DataSource hikariDataSource) {
return new DataSourceProxy(hikariDataSource);
}
@Bean
public GlobalTransactionScanner globalTransactionScanner() {
/**
* applicationId:同服务名即可
* txServiceGroup:自定义事务组名,需要与 Seata Server 配置一致
*/
return new GlobalTransactionScanner("provider-order-item", "tx_group");
}
}
Be sure to add to the startup class@EnableTransactionManagement
transaction
We go here to remove mybatis mysql hikari
the dependency.
Configuration class
import io.seata.spring.annotation.GlobalTransactionScanner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SeataConfiguration {
@Bean
public GlobalTransactionScanner globalTransactionScanner() {
return new GlobalTransactionScanner("consumer-transaction", "tx_group");
}
}
Annotate the implementation method@GlobalTransactional
@Service(version = "1.0.0")
public class TransactionServiceImpl implements TransactionService {
@Reference(version = "1.0.0")
private OrderService orderService;
@Reference(version = "1.0.0")
private OrderItemService orderItemService;
@Override
@GlobalTransactional
public void doTransaction(TbOrder tbOrder, TbOrderItem tbOrderItem) throws Exception {
System.out.println("transaction 开始全局事务,XID = " + RootContext.getXID());
orderService.insert(tbOrder);
orderItemService.insert(tbOrderItem);
if (tbOrderItem.getOrderId() == null ) {
throw new RuntimeException(" null Exception ");
}
}
}
business
Call here normallyconsumer
@RestController
@RequestMapping("/v1/transaction")
public class TransactionController {
@Reference(version = "1.0.0")
private TransactionService transactionService;
@GetMapping("")
public Map<String,Object> doTransaction() throws Exception {
TbOrder order = new TbOrder();
order.setOrderId(1L);
order.setUserId(1L);
TbOrderItem orderItem = new TbOrderItem();
orderItem.setUserId(1L);
transactionService.doTransaction(order,orderItem);
Map<String,Object> map = new HashMap<>();
map.put("code",200);
map.put("message","服务调用成功");
return map;
}
}
Next is the browser access test http://127.0.0.1:27010/v1/transaction
and then Seata
see the rollback log on the service, and then check the database. Roll back successfully
nacos-http
(TBD)
nacos-http
It is an introductory project using the Spring Cloud Alibaba
realization Seata AT
pattern.