diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0b13fed --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +### self for lingh ### +.idea diff --git a/springboot-example/seata-consumer/build.gradle b/springboot-example/seata-consumer/build.gradle index 794925b..729ad29 100644 --- a/springboot-example/seata-consumer/build.gradle +++ b/springboot-example/seata-consumer/build.gradle @@ -1,6 +1,6 @@ plugins { id 'java' - id 'org.springframework.boot' version '3.3.0' + id 'org.springframework.boot' version '3.3.1' id 'io.spring.dependency-management' version '1.1.5' } @@ -28,19 +28,19 @@ dependencies { compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.mysql:mysql-connector-j' annotationProcessor 'org.projectlombok:lombok' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' implementation('org.apache.shardingsphere:shardingsphere-jdbc:5.5.0') { exclude group: "org.apache.shardingsphere", module: "shardingsphere-test-util" } implementation 'org.apache.shardingsphere:shardingsphere-transaction-base-seata-at:5.5.0' - implementation ('io.seata:seata-spring-boot-starter:2.0.0') { + implementation('io.seata:seata-spring-boot-starter:2.0.0') { exclude group: 'org.antlr', module: 'antlr4-runtime' } - implementation ('com.baomidou:mybatis-plus-boot-starter:3.5.6') { + implementation('com.baomidou:mybatis-plus-boot-starter:3.5.6') { exclude group: 'org.mybatis', module: 'mybatis-spring' } implementation 'org.mybatis:mybatis-spring:3.0.3' - testImplementation 'org.springframework.boot:spring-boot-starter-test' - testRuntimeOnly 'org.junit.platform:junit-platform-launcher' testImplementation 'org.springframework.experimental.boot:spring-boot-testjars:0.0.1' testImplementation 'org.testcontainers:mysql' testImplementation 'org.testcontainers:junit-jupiter' @@ -48,4 +48,4 @@ dependencies { tasks.named('test') { useJUnitPlatform() -} \ No newline at end of file +} diff --git a/springboot-example/seata-consumer/src/main/java/com/youyi/seataconsumer/ConsumerController.java b/springboot-example/seata-consumer/src/main/java/com/youyi/seataconsumer/ConsumerController.java index 3910180..f6f4c09 100644 --- a/springboot-example/seata-consumer/src/main/java/com/youyi/seataconsumer/ConsumerController.java +++ b/springboot-example/seata-consumer/src/main/java/com/youyi/seataconsumer/ConsumerController.java @@ -1,7 +1,6 @@ package com.youyi.seataconsumer; import com.baomidou.mybatisplus.core.toolkit.Wrappers; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Transactional; @@ -9,23 +8,25 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; -import java.net.URI; import java.util.Map; import java.util.Objects; @RestController public class ConsumerController { - @Autowired - AccountMapper accountMapper; + final AccountMapper accountMapper; - @Autowired - RestTemplate restTemplate; + final RestTemplate restTemplate; @Value("${provider.port}") String port; + public ConsumerController(AccountMapper accountMapper, RestTemplate restTemplate) { + this.accountMapper = accountMapper; + this.restTemplate = restTemplate; + } + @SuppressWarnings({"NumericOverflow", "divzero", "unused"}) @GetMapping("consume") @Transactional public String consume(Long id) { diff --git a/springboot-example/seata-consumer/src/main/java/com/youyi/seataconsumer/RestTemplateConfig.java b/springboot-example/seata-consumer/src/main/java/com/youyi/seataconsumer/RestTemplateConfig.java index e89514a..e4e2fac 100644 --- a/springboot-example/seata-consumer/src/main/java/com/youyi/seataconsumer/RestTemplateConfig.java +++ b/springboot-example/seata-consumer/src/main/java/com/youyi/seataconsumer/RestTemplateConfig.java @@ -1,11 +1,6 @@ package com.youyi.seataconsumer; import io.seata.core.context.RootContext; -import org.apache.ibatis.session.SqlSessionFactory; -import org.mybatis.spring.SqlSessionFactoryBean; -import org.mybatis.spring.annotation.MapperScan; -import org.mybatis.spring.annotation.MapperScans; -import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -13,9 +8,9 @@ import org.springframework.http.client.ClientHttpRequestExecution; import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.http.client.ClientHttpResponse; +import org.springframework.lang.NonNull; import org.springframework.web.client.RestTemplate; -import javax.sql.DataSource; import java.io.IOException; @Configuration @@ -32,7 +27,8 @@ public RestTemplate restTemplate() { static class RestTemplateInterceptor implements ClientHttpRequestInterceptor { @Override - public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { + @NonNull + public ClientHttpResponse intercept(HttpRequest request, @NonNull byte[] body, ClientHttpRequestExecution execution) throws IOException { // 将 TX_XID 放入请求头 request.getHeaders().add(RootContext.KEY_XID, RootContext.getXID()); return execution.execute(request, body); diff --git a/springboot-example/seata-consumer/src/main/java/com/youyi/seataconsumer/SeataConsumerApplication.java b/springboot-example/seata-consumer/src/main/java/com/youyi/seataconsumer/SeataConsumerApplication.java index 39e7823..bf66606 100644 --- a/springboot-example/seata-consumer/src/main/java/com/youyi/seataconsumer/SeataConsumerApplication.java +++ b/springboot-example/seata-consumer/src/main/java/com/youyi/seataconsumer/SeataConsumerApplication.java @@ -1,18 +1,8 @@ package com.youyi.seataconsumer; -import io.seata.core.context.RootContext; import io.seata.spring.boot.autoconfigure.SeataAutoConfiguration; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.context.annotation.Bean; -import org.springframework.http.HttpRequest; -import org.springframework.http.client.ClientHttpRequestExecution; -import org.springframework.http.client.ClientHttpRequestInterceptor; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.web.client.RestTemplate; - -import java.io.IOException; // 排除 SeataAutoConfiguration @SpringBootApplication(exclude = SeataAutoConfiguration.class) diff --git a/springboot-example/seata-consumer/src/test/java/com/youyi/seataconsumer/ConsumerControllerTests.java b/springboot-example/seata-consumer/src/test/java/com/youyi/seataconsumer/ConsumerControllerTests.java index 0b5bf3f..001b07e 100644 --- a/springboot-example/seata-consumer/src/test/java/com/youyi/seataconsumer/ConsumerControllerTests.java +++ b/springboot-example/seata-consumer/src/test/java/com/youyi/seataconsumer/ConsumerControllerTests.java @@ -1,23 +1,16 @@ package com.youyi.seataconsumer; -import com.github.dockerjava.api.model.ExposedPort; -import com.github.dockerjava.api.model.HostConfig; -import com.github.dockerjava.api.model.Ports; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.jdbc.DataSourceBuilder; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Bean; -import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.MySQLContainer; import javax.sql.DataSource; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +@SuppressWarnings({"SqlDialectInspection", "SqlNoDataSourceInspection"}) public class ConsumerControllerTests extends AbstractTests { /** @@ -39,11 +32,11 @@ public class ConsumerControllerTests extends AbstractTests { * datasource3307: id(1), money(300.0) */ @Test - void testConsumerController() throws Exception { - Assertions.assertThrows(ArithmeticException.class, () -> consumerController.consume(1L)); - Assertions.assertEquals(100.0, getMoney(dataSource3306())); + void testConsumerController() { + assertThrows(ArithmeticException.class, () -> consumerController.consume(1L)); + assertEquals(100.0, getMoney(dataSource3306())); // the below assertion will fail - Assertions.assertEquals(100.0, getMoney(dataSource3307())); + assertEquals(100.0, getMoney(dataSource3307())); } private double getMoney(DataSource datasource) { @@ -52,7 +45,8 @@ private double getMoney(DataSource datasource) { ResultSet resultSet = ps.executeQuery()) { resultSet.next(); return resultSet.getDouble("money"); - } catch (Exception ignored) {} + } catch (Exception ignored) { + } return 0.0; } } diff --git a/springboot-example/seata-consumer/src/test/java/com/youyi/seataconsumer/SeataConsumerApplicationTests.java b/springboot-example/seata-consumer/src/test/java/com/youyi/seataconsumer/SeataConsumerApplicationTests.java index bf1fd2a..8506531 100644 --- a/springboot-example/seata-consumer/src/test/java/com/youyi/seataconsumer/SeataConsumerApplicationTests.java +++ b/springboot-example/seata-consumer/src/test/java/com/youyi/seataconsumer/SeataConsumerApplicationTests.java @@ -26,5 +26,4 @@ static CommonsExecWebServerFactoryBean providerBean() { .mainClass("org.springframework.boot.loader.launch.JarLauncher") .classpath(cp -> cp.files("../seata-provider/build/libs/seata-provider-shardingsphere-sb-0.0.1-SNAPSHOT.jar")); } - } diff --git a/springboot-example/seata-consumer/src/test/resources/init.sql b/springboot-example/seata-consumer/src/test/resources/init.sql index 991f122..760d2a8 100644 --- a/springboot-example/seata-consumer/src/test/resources/init.sql +++ b/springboot-example/seata-consumer/src/test/resources/init.sql @@ -16,4 +16,4 @@ CREATE TABLE IF NOT EXISTS `undo_log` `log_modified` DATETIME(6) NOT NULL COMMENT 'modify datetime', UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`) ) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table'; -ALTER TABLE `undo_log` ADD INDEX `ix_log_created` (`log_created`); \ No newline at end of file +ALTER TABLE `undo_log` ADD INDEX `ix_log_created` (`log_created`); diff --git a/springboot-example/seata-provider/build.gradle b/springboot-example/seata-provider/build.gradle index 50c9c1b..54962c2 100644 --- a/springboot-example/seata-provider/build.gradle +++ b/springboot-example/seata-provider/build.gradle @@ -1,6 +1,6 @@ plugins { id 'java' - id 'org.springframework.boot' version '3.3.0' + id 'org.springframework.boot' version '3.3.1' id 'io.spring.dependency-management' version '1.1.5' } @@ -28,15 +28,21 @@ dependencies { compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.mysql:mysql-connector-j' annotationProcessor 'org.projectlombok:lombok' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' implementation('org.apache.shardingsphere:shardingsphere-jdbc:5.5.0') { exclude group: "org.apache.shardingsphere", module: "shardingsphere-test-util" } implementation 'org.apache.shardingsphere:shardingsphere-transaction-base-seata-at:5.5.0' - implementation ('io.seata:seata-spring-boot-starter:2.0.0') { + implementation('io.seata:seata-spring-boot-starter:2.0.0') { exclude group: 'org.antlr', module: 'antlr4-runtime' } - implementation ('com.baomidou:mybatis-plus-boot-starter:3.5.6') { + implementation('com.baomidou:mybatis-plus-boot-starter:3.5.6') { exclude group: 'org.mybatis', module: 'mybatis-spring' } implementation 'org.mybatis:mybatis-spring:3.0.3' -} \ No newline at end of file +} + +tasks.named('test') { + useJUnitPlatform() +} diff --git a/springboot-example/seata-provider/src/main/java/com/youyi/seataprovider/MySeataConfigure.java b/springboot-example/seata-provider/src/main/java/com/youyi/seataprovider/MySeataConfigure.java index 2a460b2..76512af 100644 --- a/springboot-example/seata-provider/src/main/java/com/youyi/seataprovider/MySeataConfigure.java +++ b/springboot-example/seata-provider/src/main/java/com/youyi/seataprovider/MySeataConfigure.java @@ -2,14 +2,12 @@ import io.seata.common.util.StringUtils; import io.seata.core.context.RootContext; -import io.seata.core.exception.TransactionException; -import io.seata.core.model.BranchType; -import io.seata.integration.http.JakartaTransactionPropagationInterceptor; -import io.seata.integration.http.TransactionPropagationInterceptor; import io.seata.tm.api.GlobalTransactionContext; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.shardingsphere.transaction.base.seata.at.SeataTransactionHolder; import org.springframework.context.annotation.Configuration; -import org.springframework.transaction.interceptor.TransactionInterceptor; +import org.springframework.lang.NonNull; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -22,7 +20,7 @@ public void addInterceptors(InterceptorRegistry registry) { } static class ShardingSphereInterceptor implements HandlerInterceptor { - public boolean preHandle(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response, Object handler) throws TransactionException { + public boolean preHandle(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler) { String xid = RootContext.getXID(); if (xid == null) { xid = request.getHeader(RootContext.KEY_XID); diff --git a/springboot-example/seata-provider/src/main/java/com/youyi/seataprovider/ProviderController.java b/springboot-example/seata-provider/src/main/java/com/youyi/seataprovider/ProviderController.java index 3d6a6ec..a912f43 100644 --- a/springboot-example/seata-provider/src/main/java/com/youyi/seataprovider/ProviderController.java +++ b/springboot-example/seata-provider/src/main/java/com/youyi/seataprovider/ProviderController.java @@ -1,15 +1,17 @@ package com.youyi.seataprovider; import com.baomidou.mybatisplus.core.toolkit.Wrappers; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class ProviderController { - @Autowired - AccountMapper accountMapper; + final AccountMapper accountMapper; + + public ProviderController(AccountMapper accountMapper) { + this.accountMapper = accountMapper; + } @GetMapping("provide") @Transactional