MyCat和Sharding-JDBC的分布式事務


一、MyCat中使用分布式事務

1、數據准備

以前面介紹的用戶表數據為例 兩台Mysql  192.168.127.134 (dn0) ,192.168.127.129 (dn1) , Mycat 安裝在192.168.127.129

如下圖所示

 

 

Mycat的配置,

1)、schema.xml配置

分片規則為sharding-by-intfile

cd /usr/local/mycat/conf/

cat schema.xml

 

 

2)、 cat  rule.xml

 

 使用的是provice_id 作為分片的字段

 

hash-int使用的是partition-hash-int.txt文件

        <function name="hash-int"
                class="io.mycat.route.function.PartitionByFileMap">
                <property name="mapFile">partition-hash-int.txt</property>
                <property name="defaultNode">0</property>
        </function>

  

3)、cat  partition-hash-int.txt

 

 10000 落在dn0, 10010落在dn1, 默認是dn0

 

2、Mycat分布式事務配置

cat server.xml

<!--分布式事務開關,0為不過濾分布式事務,1為過濾分布式事務(如果分布式事務內只涉及全局表,則不過濾),2為不過濾分布式事務,但是記錄分布式事務日志-->
                <property name="handleDistributedTransactions">0</property>

0: 支持分布式事務, 1: 不支持分布式事務

默認是支持分布式事務。

 

 

3、插入數據

先清空134和129中user表的數據

然后在MyCat中插入數據

INSERT into `user`(`id`,`username`,`province_id`) VALUES (1,"Larry1",10000),(2,"Larry2",10010);

  可以看到134和129各插入1條數據

 

 

4、模擬異常情況

先清空134和129中user表的數據,然后將129的username長度改為1

 

 可以發現報如下錯誤

 

 查看134和129中user表的數據,都沒有插入成。

set autocommit=0 
set xa=on 
INSERT into `user`(`id`,`username`,`province_id`) VALUES (1,"Larry1",10000),(2,"Larry2",10010);
commit 

  

 

二、項目中連接MyCat,並使用分布式事務

1、新建SpringBoot工程

 

 

命名為mycat-demo

 

 

選擇需要的依賴

 

因為MySQL數據庫的版本 是5.7。所有這里使用的mysql-connector-java版本為5.1.48

<dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.48</version>
        </dependency>

  

 

2、使用mybatis-generator插件

pom.xml中增加插件

            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.2</version>
                <configuration>
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                </configuration>
            </plugin>

  

generatorConfig.xml,連接mycat

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>

    <!--指定特定數據庫的jdbc驅動jar包的位置-->
    <classPathEntry location="C:\Users\Think\Desktop\MyBatis\mybatis-generator-core-1.3.2\mybatis-generator-core-1.3.2\lib\mysql-connector-java-5.1.29.jar"/>

    <context id="default" targetRuntime="MyBatis3">

        <!-- optional,旨在創建class時,對注釋進行控制 -->
        <commentGenerator>
            <property name="suppressDate" value="true"/>
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>

        <!--jdbc的數據庫連接 -->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                        connectionURL="jdbc:mysql://192.168.127.129:8066/user?characterEncoding=utf8" userId="root"
                        password="123456" />


        <!-- 非必需,類型處理器,在數據庫類型和java類型之間的轉換控制-->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>


        <!-- Model模型生成器,用來生成含有主鍵key的類,記錄類 以及查詢Example類
            targetPackage     指定生成的model生成所在的包名
            targetProject     指定在該項目下所在的路徑
        -->
        <javaModelGenerator targetPackage="com.example.mycatdemo.model" targetProject="./src/main/java">
            <!-- 是否允許子包,即targetPackage.schemaName.tableName -->
            <property name="enableSubPackages" value="false"/>
            <!-- 是否對model添加 構造函數 -->
            <property name="constructorBased" value="true"/>
            <!-- 是否對類CHAR類型的列的數據進行trim操作 -->
            <property name="trimStrings" value="true"/>
            <!-- 建立的Model對象是否 不可改變  即生成的Model對象不會有 setter方法,只有構造方法 -->
            <property name="immutable" value="false"/>
        </javaModelGenerator>

        <!--mapper映射文件生成所在的目錄 為每一個數據庫的表生成對應的SqlMap文件 -->
        <sqlMapGenerator targetPackage="mappers" targetProject="./src/main/resources">
            <property name="enableSubPackages" value="false"/>
        </sqlMapGenerator>

        <javaClientGenerator type="XMLMAPPER" targetPackage="com.example.mycatdemo.dao" targetProject="./src/main/java">
            <!-- enableSubPackages:是否讓schema作為包的后綴 -->
            <property name="enableSubPackages" value="false" />
        </javaClientGenerator>
        
        <table schema="user" tableName="user" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>

    </context>
</generatorConfiguration>

  

生成后的工程結構如下圖所示

 

 

3、增加數據庫配置 application.prooperties

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://192.168.127.129:8066/user?characterEncoding=utf8&useSSL=false

mybatis.mapper-locations=mappers/*.xml

  

 

4、增加服務層代碼

@Service
public class UserService {

    @Resource
    private UserMapper userMapper;

    @Transactional(rollbackFor = Exception.class)
    public void testUser(){
        User user1 = new User();
        user1.setId(1);
        user1.setUsername("Nick1");
        user1.setProvinceId(10000);
        userMapper.insert(user1);


        User user2 = new User();
        user2.setId(2);
        user2.setUsername("Nick2");
        user2.setProvinceId(10010);
        userMapper.insert(user2);

    }
}

  

5、測試

@SpringBootTest
class MycatDemoApplicationTests {

    @Autowired
    UserService userService;


    @Test
    public void testUser(){
        userService.testUser();
    }

}  

運行testUser方法,出現如下錯誤: username太長了

 

注:Sharding-JDBC默認也是開啟了分布式事務


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM