zoukankan      html  css  js  c++  java
  • 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:UsersThinkDesktopMyBatismybatis-generator-core-1.3.2mybatis-generator-core-1.3.2libmysql-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默认也是开启了分布式事务

  • 相关阅读:
    bzoj1101 [POI2007]Zap
    bzoj2648/2716 kdtree
    bzoj2850巧克力王国
    【bzoj1193】[HNOI2006]马步距离
    bzoj 4401 块的计数 思想+模拟+贪心
    【bzoj2751】[HAOI2012]容易题(easy) 数论,简单题
    Ubuntu分区小知识与分区方案
    Ubuntu16.04安装x11VNC远程桌面
    Ubuntu用户权限管理(chown, chmod)
    Ubuntu新建用户组
  • 原文地址:https://www.cnblogs.com/linlf03/p/14004666.html
Copyright © 2011-2022 走看看