项目场景:
单元测试shardingsphere-jdbc的分布式事务碰到的问题集合
问题描述
最近在学习shardingsphere,没想到刚开始就给我绊一跟头,在这里集中记录一下所遇到的问题,引以为戒的同时,希望给其他遇到相同问题的小伙伴一个解决思路。
基础准备
言归正传,最开始的时候,按照网上一些教程,我做了如下准备:
两个测试库:db2022和sakila
两张测试表:position、position_detail
由于想要测试分库分表下的分布式事务,所以两个库都有position、position_detail表
表建好了,接下来就是配置:
首先是properties文件的配置:
spring.shardingsphere.datasource.names=ds0,ds1
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds0.jdbc-url=jdbc:mysql://localhost:3306/db2022?useSSL=false
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=root
spring.shardingsphere.datasource.ds1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds1.jdbc-url=jdbc:mysql://localhost:3306/sakila?useSSL=false
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=root
# 分片策略:database-strategy按数据库分片 以什么方式去查询:行表达式inline
spring.shardingsphere.sharding.tables.position.database-strategy.inline.sharding-column=id
# 路由规则:按主键mod2的值路由
spring.shardingsphere.sharding.tables.position.database-strategy.inline.algorithm-expression=ds${
id % 2}
spring.shardingsphere.sharding.tables.position_detail.database-strategy.inline.sharding-column=pid
spring.shardingsphere.sharding.tables.position_detail.database-strategy.inline.algorithm-expression=ds${
pid % 2}
接下来是写一个启动类,因为测试不需要前端参与,不需要以应用的方式一直运行,所以main方法可以省略,在test里进行指定启动类即可
@SpringBootApplication
@EnableTransactionManagement
public class RunBoot {
}
然后是基于JPA的dao层代码和entity层代码,这里就不赘述了
分布式事务的部分
先写一个test类:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {
RunBoot.class})
public class TestShardingTransaction {
@Resource
private PositionRepository positionRepository;
@Resource
private PositionDetailRepository positionDetailRepository;
@Test
@Transactional
public void test1(){
for (int i = 1; i <= 3; i++) {
Position position = new Position();
position.setName("root" + i);
position.setSalary("1000000");
position.setCity("beijing");
positionRepository.save(position);
// if (i == 3) {
// throw new RuntimeException("人为制造异常");
//