Rumah  >  Artikel  >  Java  >  Spring Boot+MyBatis+Atomikos+MySQL (dengan kod sumber)

Spring Boot+MyBatis+Atomikos+MySQL (dengan kod sumber)

Java后端技术全栈
Java后端技术全栈ke hadapan
2023-08-15 16:12:53635semak imbas

Dalam projek sebenar, kami cuba mengelakkan transaksi yang diedarkan. Walau bagaimanapun, kadangkala ia benar-benar perlu untuk melakukan beberapa pemisahan perkhidmatan, yang akan membawa kepada masalah transaksi yang diedarkan.

Pada masa yang sama, transaksi yang diedarkan juga ditanya di pasaran semasa temuduga Anda boleh berlatih dengan kes ini, dan anda boleh bercakap 123 dalam temuduga.

Berikut ialah berangan perniagaan: apabila pengguna menerima kupon, bilangan kali pengguna menerima kupon perlu ditolak, dan kemudian rekod pengguna menerima kupon direkodkan.

Spring Boot+MyBatis+Atomikos+MySQL (dengan kod sumber)
Sebelum pemisahan
Spring Boot+MyBatis+Atomikos+MySQL (dengan kod sumber)
Selepas pemisahan

Pada asalnya, kaedah baris gilir mesej boleh digunakan di sini untuk menggunakan penyegerakan untuk menambah rekod koleksi pengguna. Walau bagaimanapun, keperluan di sini ialah pengguna perlu dapat melihat rekod koleksi mereka serta-merta selepas menerimanya, jadi kami memperkenalkan Atomikos di sini untuk melaksanakan isu transaksi yang diedarkan.

Urus niaga teragih

Urus niaga teragih ialah urus niaga yang merangkumi berbilang komputer atau pangkalan data, dan mungkin terdapat kelewatan rangkaian, kegagalan atau ketidakkonsistenan antara komputer atau pangkalan data ini Urus niaga yang diedarkan perlu memastikan atomicity, konsistensi, pengasingan dan ketahanan semua operasi untuk memastikan ketepatan dan integriti data.

Apakah protokol transaksi yang diedarkan?

Terdapat dua jenis utama protokol urus niaga yang diedarkan: 2PC (Komit Dua Fasa) dan 3PC (Komit Tiga Fasa).

2PC kini merupakan protokol urus niaga teragih yang paling biasa digunakan, dan prosesnya dibahagikan kepada dua peringkat: peringkat penyediaan dan peringkat penyerahan. Dalam fasa penyediaan, penyelaras urus niaga mengeluarkan permintaan untuk semua peserta, dan peserta melaksanakan urus niaga tempatan ke keadaan penyediaan dan mengembalikan hasil penyediaan kepada penyelaras urus niaga. Dalam fasa komitmen, jika semua peserta berjaya melaksanakan, penyelaras urus niaga mengeluarkan permintaan komitmen kepada semua peserta, dan peserta melakukan transaksi tempatan Jika tidak, penyelaras urus niaga mengeluarkan permintaan balik kepada semua peserta, dan peserta melancarkan semula tempatan urus niaga.

3PC ialah versi 2PC yang dipertingkatkan, yang menambah peringkat penyediaan dan penyerahan berdasarkan 2PC. Dalam fasa persediaan untuk menghantar, penyelaras bertanya kepada peserta sama ada mereka boleh menyerahkan Jika peserta mengembalikan persetujuan, ia akan diserahkan terus dalam fasa penyerahan, jika tidak, ia akan digulung semula dalam fasa penyerahan.

Apakah penyelesaian biasa untuk transaksi yang diedarkan?

Penyelesaian pelaksanaan penyelesaian transaksi yang diedarkan termasuk:

  • Penyelesaian transaksi yang diedarkan berdasarkan baris gilir mesej (seperti penyelesaian sumber terbuka RocketMQ)
  • Penyelesaian urus niaga yang diedarkan berdasarkan sebaran TCC (rangka kerja transaksi TCC yang diedarkan berdasarkan sebaran TCC) dan rangka kerja lain)
  • Penyelesaian transaksi yang diedarkan berdasarkan protokol XA (seperti JTA, dll.)
  • Penyelesaian transaksi yang diedarkan berdasarkan ketekalan akhirnya mesej yang boleh dipercayai (seperti GTS urus niaga yang diedarkan Alibaba)
  • penyelesaian transaksi berdasarkan prinsip CAP (seperti mod sumber acara dalam seni bina CQRS)

Apakah itu JTA?

JTA (Java Transaction API) ialah spesifikasi antara muka pengaturcaraan J2EE Ia adalah pelaksanaan JAVA bagi protokol XA. Ia mentakrifkan terutamanya:

Antara muka pengurus transaksi javax.transaction .TransactionManager, mentakrifkan operasi permulaan, komit, pengeluaran, dsb. transaksi.

javax.transaction.TransactionManager,定义了有关事务的开始、提交、撤回等>操作。

一个满足XA规范的资源定义接口javax.transaction.xa.XAResource,一种资源如果要支持JTA事务,就需要让它的资源实现该XAResourceAntara muka definisi sumber yang memenuhi spesifikasi XAjavax. transaksi .xa.XAResource, jika sumber ingin menyokong transaksi JTA, sumbernya perlu melaksanakan XAResource antara muka, dan melaksanakan antara muka berkaitan penyerahan dua fasa yang ditakrifkan oleh antara muka ini. Jika kita mempunyai aplikasi yang menggunakan antara muka JTA untuk melaksanakan transaksi, apabila aplikasi sedang berjalan, ia memerlukan bekas yang melaksanakan JTA Secara amnya, ini adalah bekas J2EE, seperti JBoss, Websphere dan pelayan aplikasi lain.

Namun, terdapat juga beberapa rangka kerja bebas yang melaksanakan JTA, seperti Atomikos dan bitronix, yang menyediakan rangka kerja pelaksanaan JTA dalam bentuk pakej balang. Dengan cara ini, kita boleh menjalankan sistem aplikasi yang menggunakan JTA untuk melaksanakan transaksi pada pelayan seperti Tomcat atau Jetty.

Seperti yang dinyatakan dalam perbezaan antara urus niaga tempatan dan urus niaga luar di atas, urus niaga JTA ialah urus niaga luar dan boleh digunakan untuk melaksanakan transaksi untuk pelbagai sumber. Ia betul-betul melakukannya dengan setiap sumber XAResource来进行两阶段提交的控制。感兴趣的同学可以看看这个接口的方法,除了commit, rollback等方法以外,还有end(), forget(), isSameRM(), prepare() dan banyak lagi. Daripada antara muka ini sahaja, anda boleh bayangkan kerumitan JTA dalam melaksanakan transaksi dua fasa.

Apakah itu XA?

XA ialah seni bina transaksi teragih (atau protokol) yang dicadangkan oleh organisasi X/Open. Seni bina XA mentakrifkan terutamanya antara muka antara Pengurus Transaksi (global) dan Pengurus Sumber (tempatan). Antara muka XA ialah antara muka sistem dwiarah yang membentuk jambatan komunikasi antara Pengurus Transaksi dan satu atau lebih Pengurus Sumber. Dalam erti kata lain, dalam urus niaga berdasarkan XA, kita boleh melaksanakan pengurusan transaksi pada pelbagai sumber Contohnya, sistem mengakses berbilang pangkalan data, atau mengakses kedua-dua pangkalan data dan sumber seperti perisian tengah mesej. Dengan cara ini, kami boleh melaksanakan secara langsung semua transaksi yang diserahkan atau semua yang dibatalkan dalam berbilang pangkalan data dan perisian tengah mesej. Spesifikasi XA bukanlah spesifikasi Java, tetapi spesifikasi universal Pada masa ini, pelbagai pangkalan data dan banyak perisian tengah mesej menyokong spesifikasi XA.

JTA ialah spesifikasi untuk pembangunan Java yang memenuhi spesifikasi XA. Oleh itu, apabila kami mengatakan bahawa kami menggunakan JTA untuk melaksanakan transaksi teragih, kami sebenarnya bermaksud menggunakan spesifikasi JTA untuk melaksanakan transaksi dengan pelbagai pangkalan data, perisian tengah mesej dan sumber lain dalam sistem.

Apa itu Atomikos

Atomikos ialah pengurus transaksi sumber terbuka yang sangat popular dan boleh dibenamkan ke dalam aplikasi Spring Boot anda. Pelayan aplikasi Tomcat tidak melaksanakan spesifikasi JTA Apabila menggunakan Tomcat sebagai pelayan aplikasi, anda perlu menggunakan kelas pengurus transaksi pihak ketiga sebagai pengurus transaksi global, dan rangka kerja Atomikos melakukan ini, menyepadukan pengurusan transaksi ke dalam aplikasi. Tidak bergantung pada pelayan aplikasi.

Spring Boot mengintegrasikan Atomikos

Tak guna bercakap tentang sekumpulan teori, tunjukkan kodnya.

Timbunan teknologi: Spring Boot+MyBatis+Atomikos+MySQL

Jika anda mengikuti kod dalam artikel ini, perhatikan versi mysql anda.

Mula-mula bina dua pangkalan data (my-db_0 dan my-db_1), dan kemudian buat jadual dalam setiap pangkalan data.

Dalam pangkalan data my-db_0:

CREATE TABLE `t_user_0` (
`id` bigint NOT NULL AUTO_INCREMENT,
`user_name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`age` int NOT NULL,
`gender` int NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8;

Dalam pangkalan data my-db_1:

CREATE TABLE `t_user_1` (
`id` bigint NOT NULL AUTO_INCREMENT,
`user_name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`age` int NOT NULL,
`gender` int NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8;

Ini hanya untuk menunjukkan transaksi yang diedarkan, jangan risau tentang maksud khusus jadual. struktur projek keseluruhan

Sumber Data
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.tian</groupId>
    <artifactId>spring-boot-atomikos</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>jar</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.RELEASE</version>
    </parent>

    <name>spring-boot-atomikos</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!-- mybatis依赖 -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- mysql依赖 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.16</version>
        </dependency>
        <!--分布式事务-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jta-atomikos</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <!-- 要使生成的jar可运行,需要加入此插件 -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <excludes>
                    <exclude>**/*.java</exclude>
                </excludes>
            </resource>
            <resource>
                <!-- 编译xml文件 -->
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.*</include>
                </includes>
            </resource>
        </resources>
    </build>
</project>

Spring Boot+MyBatis+Atomikos+MySQL (dengan kod sumber)MyBatis Scan .
Antara muka pemeta yang sepadan juga sangat mudah. ​​Ini adalah satu:
server.port=9001
spring.application.name=atomikos-demo

spring.datasource.user0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.user0.url=jdbc:mysql://localhost:3306/my-db_0?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
spring.datasource.user0.user=root
spring.datasource.user0.password=123456

spring.datasource.user1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.user1.url=jdbc:mysql://localhost:3306/my-db_1?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
spring.datasource.user1.user=root
spring.datasource.user1.password=123456

mybatis.mapperLocations=classpath:/com/tian/mapper/*/*.xml
mybatis.typeAliasesPackage=com.tian.entity
mybatis.configuration.cache-enabled=true

perkhidmatan

/**
 * @author tianwc  公众号:java后端技术全栈、面试专栏
 * @version 1.0.0
 * @date 2023年05月11日 19:38
 * 博客地址:<a href="http://woaijava.cc/">博客地址</a>
 * <p>
 * 配置好两个数据源
 */
@Configuration
public class DataSourceConfig {

    // 将这个对象放入spring容器中(交给Spring管理)
    @Bean
    // 读取 application.yml 中的配置参数映射成为一个对象
    @ConfigurationProperties(prefix = "spring.datasource.user0")
    public XADataSource getDataSource0() {
        // 创建XA连接池
        return new MysqlXADataSource();
    }

    /**
     * 创建Atomikos数据源
     * 注解@DependsOn("druidXADataSourcePre"),在名为druidXADataSourcePre的bean实例化后加载当前bean
     */
    @Bean
    @DependsOn("getDataSource0")
    @Primary
    public DataSource dataSourcePre(@Qualifier("getDataSource0") XADataSource xaDataSource) {
        //这里的AtomikosDataSourceBean使用的是spring提供的
        AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
        atomikosDataSourceBean.setXaDataSource(xaDataSource);
        atomikosDataSourceBean.setMaxPoolSize(20);
        return atomikosDataSourceBean;
    }


    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.user1")
    public XADataSource getDataSource1() {
        // 创建XA连接池
        return new MysqlXADataSource();
    }

    @Bean
    @DependsOn("getDataSource1")
    public DataSource dataSourceSit(@Qualifier("getDataSource1") XADataSource xaDataSource) {
        //这里的AtomikosDataSourceBean使用的是spring提供的
        AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
        atomikosDataSourceBean.setXaDataSource(xaDataSource);
        return atomikosDataSourceBean;
    }
}

controller

rreee

projek reee

Ujian

Mulakan Projek, uji tiga berikut masing-masing:

http :/ /localhost:9001/user/test1 Keputusan: Dalam kedua-dua pangkalan data, data jadual baharu ditambahhttp://localhost:9001/user/test2 Keputusan: Pengecualian bahawa pembahagi tidak boleh menjadi Sifar dilemparkan dan tiada data baharu ditambahkan pada sama ada pangkalan data.

http://localhost:9001/user/test3 Keputusan: Nilai medan data yang terlalu lama dikecualikan dilemparkan dan tiada data baharu ditambahkan pada mana-mana pangkalan data.

Baiklah, sekarang kami telah melaksanakan transaksi agihan.

Atas ialah kandungan terperinci Spring Boot+MyBatis+Atomikos+MySQL (dengan kod sumber). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:Java后端技术全栈. Jika ada pelanggaran, sila hubungi admin@php.cn Padam