ShardingJdbc:Springboot集成ShardingSphere,单服务跨数据源时,简单实现事务管理

阅读下面实验之前:请先阅读官方的分布式事务支持内容:https://shardingsphere.apache.org/document/current/cn/features/transaction/

经过试验,单服务跨数据源,使用shardingJdbc的事务,同普通jdbc时的做法一样。实验版本 shrading-jdbc-spring-boot-starter ver.3.1.0

1)启动类 (前提:pom引入spring-boot-starter-jdbc或者引入spring-boot-starter-data-jpa依赖,启动类使用注解开启事务管理器@EnableTransactionManagement):

package com.chong.mcspcshardingdbtable;

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@SpringBootApplication(exclude = {DruidDataSourceAutoConfigure.class})
@EnableDiscoveryClient
@EnableTransactionManagement
@ComponentScan(basePackages = {"com.chong.common","com.chong.mcspcshardingdbtable"})
public class McSpcShardingDbTableApplication {

    public static void main(String[] args) {
        SpringApplication.run(McSpcShardingDbTableApplication.class, args);
    }

}

2)service方法引入事务注解

    @Transactional
    public List<BizMember> saveMembersToMutliDbs(String name,String name2) {
        BizMember member1 = newMember();
        member1.setFullName(name);
        member1.setGender(1); // 存放到mcspcsharding1
        BizMember member2 = newMember();
        member2.setFullName(name2);
        member2.setGender(2);// 存放到mcspcsharding0
        List<BizMember> memberList = new ArrayList<>();
        memberList.add(memberRepository.save(member1));
        memberList.add(member2 = memberRepository.save(member2));
        return memberList;
    }

3)实验之数据库构成:mcspcsharding0放置gender=2的数据;mcspcsharding1放置gender=1的数据;

4)实验步骤:通过postman,投放数据,name1符合要求,name2不符合要求(数据超长)。Rest格式为 POST: url/{name1}/{name2}

5)实验结果:

    A.可以看出第一条语句插入name1的会员执行通过,第二条语句插入name2的语句执行失败,失败原因为name2的参数内容长度超出数据库列长的限制。

    B.数据库中确认实际入库记录,name1和name2的数据都没有插入到数据库中。证明通过简单的两个事物注解,实现了跨数据源的事务控制。

       todo:两个库的事务commit和rollback机制在shardingjdbc里如何实现的,需要抽空研究。

console内容:

2020-02-29 19:10:47.962  INFO 24132 --- [io-9060-exec-10] ShardingSphere-SQL                       : Rule Type: sharding
2020-02-29 19:10:47.966  INFO 24132 --- [io-9060-exec-10] ShardingSphere-SQL                       : Logic SQL: insert into mc_member (age, create_time, create_user, full_name, gender, is_delete, update_time, update_user, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?)
2020-02-29 19:10:47.971  INFO 24132 --- [io-9060-exec-10] ShardingSphere-SQL                       : SQLStatement: InsertStatement(super=DMLStatement(super=io.shardingsphere.core.parsing.parser.sql.dml.insert.InsertStatement@68a542c3), columns=[Column(name=age, tableName=mc_member), Column(name=create_time, tableName=mc_member), Column(name=create_user, tableName=mc_member), Column(name=full_name, tableName=mc_member), Column(name=gender, tableName=mc_member), Column(name=is_delete, tableName=mc_member), Column(name=update_time, tableName=mc_member), Column(name=update_user, tableName=mc_member), Column(name=id, tableName=mc_member)], generatedKeyConditions=[], insertValues=InsertValues(insertValues=[InsertValue(type=VALUES, expression=(?, ?, ?, ?, ?, ?, ?, ?, ?), parametersCount=9)]), columnsListLastPosition=112, generateKeyColumnIndex=-1, insertValuesListLastPosition=148)
2020-02-29 19:10:47.976  INFO 24132 --- [io-9060-exec-10] ShardingSphere-SQL                       : Actual SQL: ms1 ::: insert into mc_member0 (age, create_time, create_user, full_name, gender, is_delete, update_time, update_user, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?) ::: [[45, 2020-02-29 19:09:41.749, 245, name12, 1, 0, null, null, 4041594688888832]]
Hibernate: insert into mc_member (age, create_time, create_user, full_name, gender, is_delete, update_time, update_user, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?)
2020-02-29 19:10:47.999  INFO 24132 --- [io-9060-exec-10] ShardingSphere-SQL                       : Rule Type: sharding
2020-02-29 19:10:48.001  INFO 24132 --- [io-9060-exec-10] ShardingSphere-SQL                       : Logic SQL: insert into mc_member (age, create_time, create_user, full_name, gender, is_delete, update_time, update_user, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?)
2020-02-29 19:10:48.002  INFO 24132 --- [io-9060-exec-10] ShardingSphere-SQL                       : SQLStatement: InsertStatement(super=DMLStatement(super=io.shardingsphere.core.parsing.parser.sql.dml.insert.InsertStatement@68a542c3), columns=[Column(name=age, tableName=mc_member), Column(name=create_time, tableName=mc_member), Column(name=create_user, tableName=mc_member), Column(name=full_name, tableName=mc_member), Column(name=gender, tableName=mc_member), Column(name=is_delete, tableName=mc_member), Column(name=update_time, tableName=mc_member), Column(name=update_user, tableName=mc_member), Column(name=id, tableName=mc_member)], generatedKeyConditions=[], insertValues=InsertValues(insertValues=[InsertValue(type=VALUES, expression=(?, ?, ?, ?, ?, ?, ?, ?, ?), parametersCount=9)]), columnsListLastPosition=112, generateKeyColumnIndex=-1, insertValuesListLastPosition=148)
2020-02-29 19:10:48.002  INFO 24132 --- [io-9060-exec-10] ShardingSphere-SQL                       : Actual SQL: ms0 ::: insert into mc_member0 (age, create_time, create_user, full_name, gender, is_delete, update_time, update_user, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?) ::: [[73, 2020-02-29 19:09:41.75, 873, name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1name1, 2, 0, null, null, 4041594693083136]]
2020-02-29 19:10:48.020  WARN 24132 --- [io-9060-exec-10] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 1406, SQLState: 22001
2020-02-29 19:10:48.020 ERROR 24132 --- [io-9060-exec-10] o.h.engine.jdbc.spi.SqlExceptionHelper   : Data truncation: Data too long for column 'full_name' at row 1
2020-02-29 19:10:48.043 ERROR 24132 --- [io-9060-exec-10] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; nested exception is org.hibernate.exception.DataException: could not execute statement] with root cause

com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Data too long for column 'full_name' at row 1
    at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:104) ~[mysql-connector-java-8.0.19.jar:8.0.19]
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953) ~[mysql-connector-java-8.0.19.jar:8.0.19]
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1092) ~[mysql-connector-java-8.0.19.jar:8.0.19]
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1040) ~[mysql-connector-java-8.0.19.jar:8.0.19]
原文地址:https://www.cnblogs.com/chongpf/p/12393924.html