官方地址:https://shardingsphere.apache.org/document/legacy/4.x/document/cn/features/transaction/function/base-transaction-seata/
https://shardingsphere.apache.org/document/legacy/4.x/document/cn/manual/sharding-jdbc/usage/transaction/
数据库事务需要满足ACID(原子性、一致性、隔离性、持久性)四个特性。
- 原子性(Atomicity)指事务作为整体来执行,要么全部执行,要么全不执行。
- 一致性(Consistency)指事务应确保数据从一个一致的状态转变为另一个一致的状态。
- 隔离性(Isolation)指多个事务并发执行时,一个事务的执行不应影响其他事务的执行。
- 持久性(Durability)指已提交的事务修改数据会被持久保存。
在单一数据节点中,事务仅限于对单一数据库资源的访问控制,称之为本地事务。几乎所有的成熟的关系型数据库都提供了对本地事务的原生支持。 但是在基于微服务的分布式应用环境下,越来越多的应用场景要求对多个服务的访问及其相对应的多个数据库资源能纳入到同一个事务当中,分布式事务应运而生。
关系型数据库虽然对本地事务提供了完美的ACID原生支持。 但在分布式的场景下,它却成为系统性能的桎梏。如何让数据库在分布式场景下满足ACID的特性或找寻相应的替代方案,是分布式事务的重点工作。
操作
需要额外部署Seata-server服务进行分支事务的协调
ShardingSphere和Seata会对SQL进行重复解析
1.导入分布式事务的依赖
<!--依赖sharding-->
<dependency>
<groupId>io.shardingsphere</groupId>
<artifactId>sharding-transaction-spring-boot-starter</artifactId>
<version>3.1.0</version>
</dependency>
2.错误代码
package com.xuexiangban.shardingjdbc.service;
import com.xuexiangban.shardingjdbc.entity.Order;
import com.xuexiangban.shardingjdbc.entity.User;
import com.xuexiangban.shardingjdbc.mapper.OrderMapper;
import com.xuexiangban.shardingjdbc.mapper.UserMapper;
import io.shardingsphere.transaction.annotation.ShardingTransactionType;
import io.shardingsphere.transaction.api.TransactionType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* @author: 学相伴-飞哥
* @description: UserService
* @Date : 2021/3/14
*/
@Service
public class UserOrderService {
@Autowired
private UserMapper userMapper;
@Autowired
private OrderMapper orderMapper;
@ShardingTransactionType(TransactionType.XA)
@Transactional(rollbackFor = Exception.class)
public int saveUserOrder(User user, Order order) {
userMapper.addUser(user);
order.setUserid(user.getId());
orderMapper.addOrder(order);
//int a = 1/0; //测试回滚,统一提交的话,将这行注释掉就行
return 1;
}
}
3.测试
package com.xuexiangban.shardingjdbc;
import com.xuexiangban.shardingjdbc.entity.Order;
import com.xuexiangban.shardingjdbc.entity.User;
import com.xuexiangban.shardingjdbc.entity.UserOrder;
import com.xuexiangban.shardingjdbc.mapper.UserOrderMapper;
import com.xuexiangban.shardingjdbc.service.UserOrderService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
@SpringBootTest
class ShardingJdbcApplicationTests {
@Autowired
private UserOrderService userOrderService;
@Test
void contextLoads() throws Exception {
User user = new User();
user.setNickname("zhangsan" + new Random().nextInt());
user.setPassword("1234567");
user.setSex(1);
user.setAge(2);
user.setBirthday(new Date());
Order order = new Order();
order.setCreateTime(new Date());
order.setOrdernumber("133455678");
order.setProductid(1234L);
userOrderService.saveUserOrder(user, order);
}
}