shuikan95 opened a new issue, #24913:
URL: https://github.com/apache/shardingsphere/issues/24913

   Hello:
   ```
      First of all, I create a MGR on MySQL 8.0.25 what are they one Primary 
and two SECONDARY.
      I have a problem which is readwrite-splitting when using Spring Data JPA. 
      It's not working well and the version is 5.3.1 in ShardingSphere Proxy or 
ShardingSphere JDBC. 
      I write a simple Query method and no other codes to access database, but 
the logs show using a write datasource and there are the same results when 
accessing many times. 
      I have no idea why not using readDataSourceNames. I'am not sure this is a 
bug. Anybody can help me to find the reason, thanks.
   ```
      Some demo files as listed below:
   
    > build.gradle
   ```groovy
      buildscript {
       ext {
           lombokVersion = '1.18.24'
           springBootVersion = '2.6.11'
           springCloudVersion = '2021.0.5'
           springCloudAlibabaVersion = '2021.0.4.0'
           colaVersion = '4.3.1'
           shardingsphere = '5.3.1'
       }
   
       repositories {
           mavenLocal()
           maven { url 'https://maven.aliyun.com/repository/public' }
           mavenCentral()
       }
   
       dependencies {
           
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
       }
   
   }
   
   plugins {
       id 'org.springframework.boot' version '2.6.11'
       id 'io.spring.dependency-management' version '1.0.13.RELEASE'
   }
   
   allprojects {
   
       apply plugin: 'java'
       apply plugin: 'java-library'
       apply plugin: 'idea'
   
       group "com.lab.demo"
       version "1.0-SNAPSHOT"
   
       sourceCompatibility = 17
       targetCompatibility = 17
   
       tasks.withType(JavaCompile).configureEach {
           options.encoding = 'UTF-8'
       }
   
       configurations.configureEach {
           resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
           exclude module: 'slf4j-log4j12'
       }
   
       repositories {
           mavenLocal()
           maven { url 'https://maven.aliyun.com/repository/public' }
           mavenCentral()
       }
   
   }
   
   subprojects {
   
       jar {
           enabled = true
       }
   
       apply plugin: 'io.spring.dependency-management'
       apply plugin: 'org.springframework.boot'
   
       dependencies {
   
           implementation 'org.projectlombok:lombok'
           annotationProcessor 'org.projectlombok:lombok'
           annotationProcessor 
'org.springframework.boot:spring-boot-configuration-processor'
   
           testCompileOnly 'org.projectlombok:lombok'
           testAnnotationProcessor 'org.projectlombok:lombok'
           testAnnotationProcessor 
'org.springframework.boot:spring-boot-configuration-processor'
           
testImplementation('org.springframework.boot:spring-boot-starter-test')
   
           implementation "com.google.guava:guava"
           implementation "org.apache.commons:commons-lang3"
           implementation "org.apache.commons:commons-collections4"
           implementation "org.apache.commons:commons-pool2"
           implementation "org.apache.commons:commons-text"
           implementation "org.apache.commons:commons-math3"
           implementation "org.apache.commons:commons-compress"
           implementation "commons-codec:commons-codec"
   
           implementation 'com.alibaba.cola:cola-component-dto'
           implementation 'com.alibaba.cola:cola-component-exception'
           implementation 'com.alibaba.cola:cola-component-domain-starter'
   
           implementation 'com.alibaba:fastjson'
           implementation 'mysql:mysql-connector-java'
   
           implementation 
"org.springframework.boot:spring-boot-starter-validation"
           implementation "org.springframework.boot:spring-boot-starter-web"
           implementation 
'org.springframework.boot:spring-boot-starter-data-jpa'
           implementation 
"org.springframework.cloud:spring-cloud-starter-openfeign"
   
   //        implementation 'com.alibaba.nacos:nacos-client:2.2.1'
   //        implementation 'io.seata:seata-spring-boot-starter:1.6.1'
   //        
implementation("com.alibaba.cloud:spring-cloud-starter-alibaba-seata") {
   //            exclude group: "io.seata", module: "seata-spring-boot-starter"
   //        }
   //        implementation 'com.alibaba.cloud:spring-cloud-alibaba-commons'
   
   //        implementation 
"org.apache.shardingsphere:shardingsphere-jdbc-core:${shardingsphere}"
       }
   
       dependencyManagement {
           imports {
               
mavenBom("org.springframework.boot:spring-boot-dependencies:${springBootVersion}")
               
mavenBom("org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}")
               mavenBom 
"com.alibaba.cloud:spring-cloud-alibaba-dependencies:${springCloudAlibabaVersion}"
           }
           dependencies {
               dependency 'javax.annotation:javax.annotation-api:1.3.2'
               dependency "org.projectlombok:lombok:${lombokVersion}"
               dependency group: 'com.google.guava', name: 'guava', version: 
'30.1.1-jre'
   
               dependency group: 'org.apache.commons', name: 'commons-lang3', 
version: '3.12.0'
               dependency group: 'org.apache.commons', name: 
'commons-collections4', version: '4.4'
               dependency group: 'org.apache.commons', name: 'commons-pool2', 
version: '2.9.0'
               dependency group: 'org.apache.commons', name: 'commons-text', 
version: '1.9'
               dependency group: 'org.apache.commons', name: 'commons-math3', 
version: '3.6.1'
               dependency group: 'org.apache.commons', name: 
'commons-compress', version: '1.20'
               dependency group: 'commons-codec', name: 'commons-codec', 
version: '1.15'
   
               dependency group: 'mysql', name: 'mysql-connector-java', 
version: '8.0.26'
   
               dependency "com.alibaba.cola:cola-component-dto:${colaVersion}"
               dependency 
"com.alibaba.cola:cola-component-exception:${colaVersion}"
               dependency 
"com.alibaba.cola:cola-component-domain-starter:${colaVersion}"
   
               dependency 'com.alibaba:fastjson:1.2.83'
   
               dependency 'org.yaml:snakeyaml:1.33'
           }
   
       }
   
   }
   
   test {
       useJUnitPlatform()
   
       jvmArgs('--add-opens', 'java.base/java.lang=ALL-UNNAMED')
       jvmArgs('--add-opens', 'java.base/java.lang.reflect=ALL-UNNAMED')
       jvmArgs('--add-opens', 'java.base/java.util=ALL-UNNAMED')
       jvmArgs('--add-opens', 'java.base/java.util.concurrent=ALL-UNNAMED')
       jvmArgs('--add-opens', 'java.base/java.util=ALL-UNNAMED')
       jvmArgs('--add-opens', 'java.base/java.math=ALL-UNNAMED')
       jvmArgs('--add-opens', 'java.base/java.io=ALL-UNNAMED')
       jvmArgs('--add-opens', 'java.rmi/sun.rmi.transport=ALL-UNNAMED')
   }
   ```
   > application.properties
   ```yml
   spring.application.name=account-service
   server.port=8083
   
spring.datasource.url=jdbc:mysql://192.168.1.168:3333/proxy_account?useSSL=false&serverTimezone=UTC
   spring.datasource.username=sharding
   spring.datasource.password=Aa123456
   spring.jpa.show-sql=true
   spring.jpa.open-in-view=false
   ```
   
   > Account
   ```java
   import lombok.Data;
   import org.hibernate.annotations.DynamicInsert;
   import org.hibernate.annotations.DynamicUpdate;
   
   import javax.persistence.Entity;
   import javax.persistence.Id;
   import javax.persistence.Table;
   import java.math.BigDecimal;
   
   @Entity
   @Table(name = "account_tbl")
   @DynamicUpdate
   @DynamicInsert
   @Data
   public class Account {
   
       @Id
       private Long id;
       private String userId;
       private BigDecimal money;
   
   }
   ```
   
   > AccountDAO
   ```java
   import com.alibaba.demo.entity.Account;
   import org.springframework.data.jpa.repository.JpaRepository;
   
   public interface AccountDAO extends JpaRepository<Account, Long> {
   
       Account findByUserId(String userId);
   
   }
   ```
   
   > AccountService
   ```java
   import com.alibaba.cola.domain.ApplicationContextHelper;
   import com.alibaba.demo.entity.Account;
   import com.alibaba.demo.repository.AccountDAO;
   import com.zaxxer.hikari.HikariDataSource;
   import lombok.extern.slf4j.Slf4j;
   import org.springframework.beans.factory.annotation.Autowired;
   import org.springframework.stereotype.Service;
   import org.springframework.transaction.annotation.Transactional;
   
   import javax.sql.DataSource;
   import java.math.BigDecimal;
   import java.util.List;
   
   @Slf4j
   @Service
   public class AccountService {
   
       private static final String ERROR_USER_ID = "1002";
       @Autowired
       private AccountDAO accountDAO;
   
       @Transactional(rollbackFor = Exception.class)
       public void debit(String userId, BigDecimal num) {
           Account account = accountDAO.findByUserId(userId);
           account.setMoney(account.getMoney().subtract(num));
           accountDAO.save(account);
   
           if (ERROR_USER_ID.equals(userId)) {
               throw new RuntimeException("account branch exception");
           }
       }
   
       public List<Account> accountList() {
   
           List<Account> all = accountDAO.findAll();
           HikariDataSource dataSource = (HikariDataSource) 
ApplicationContextHelper.getBean(DataSource.class);
           String jdbcUrl = dataSource.getJdbcUrl();
   
           log.info("The current datasource: {}, jdbcUrl: {}", dataSource, 
jdbcUrl);
           return all;
       }
   }
   ```
   
   > AccountController
   ```java
   import com.alibaba.cola.dto.MultiResponse;
   import com.alibaba.cola.dto.Response;
   import com.alibaba.demo.entity.Account;
   import com.alibaba.demo.service.AccountService;
   import org.springframework.beans.factory.annotation.Autowired;
   import org.springframework.web.bind.annotation.GetMapping;
   import org.springframework.web.bind.annotation.RequestMapping;
   import org.springframework.web.bind.annotation.RequestParam;
   import org.springframework.web.bind.annotation.RestController;
   
   import java.math.BigDecimal;
   import java.util.List;
   
   @RestController
   public class AccountController {
   
       @Autowired
       private AccountService accountService;
   
       @RequestMapping("/debit")
       public Boolean debit(@RequestParam("userId") String userId, 
@RequestParam("money") BigDecimal money) {
           accountService.debit(userId, money);
           return true;
       }
   
       @GetMapping("/accountList")
       public Response accountList() {
           List<Account> accounts = accountService.accountList();
           return MultiResponse.of(accounts);
       }
   
   }
   ```
   
   > AccountApplication
   ```java
   import org.springframework.boot.SpringApplication;
   import org.springframework.boot.autoconfigure.SpringBootApplication;
   import org.springframework.cloud.openfeign.EnableFeignClients;
   import org.springframework.context.annotation.EnableAspectJAutoProxy;
   import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
   
   @SpringBootApplication
   @EnableFeignClients
   @EnableJpaRepositories
   @EnableAspectJAutoProxy(exposeProxy = true, proxyTargetClass = true)
   //@EnableTransactionManagement
   public class AccountApplication {
   
       public static void main(String[] args) {
           SpringApplication.run(AccountApplication.class, args);
       }
   }
   ```
   
   > config-readwrite-splitting-account.yaml in ShardingSphere Proxy conf dir
   ```yml
   databaseName: proxy_account
   
   dataSources:
     write_account:
       url: 
jdbc:mysql://192.168.1.168:3302/account?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true
       username: root
       password: root
       connectionTimeoutMilliseconds: 30000
       idleTimeoutMilliseconds: 60000
       maxLifetimeMilliseconds: 1800000
       maxPoolSize: 50
       minPoolSize: 1
     read_account_1:
       url: 
jdbc:mysql://192.168.1.168:3303/account?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true
       username: root
       password: root
       connectionTimeoutMilliseconds: 30000
       idleTimeoutMilliseconds: 60000
       maxLifetimeMilliseconds: 1800000
       maxPoolSize: 50
       minPoolSize: 1
     read_account_2:
       url: 
jdbc:mysql://192.168.1.168:3304/account?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true
       username: root
       password: root
       connectionTimeoutMilliseconds: 30000
       idleTimeoutMilliseconds: 60000
       maxLifetimeMilliseconds: 1800000
       maxPoolSize: 50
       minPoolSize: 1    
   
   rules:
   - !READWRITE_SPLITTING
     dataSources:
       readwrite_ds:
         staticStrategy:
           writeDataSourceName: write_account
           readDataSourceNames:
             - read_account_1
             - read_account_2
         loadBalancerName: random
     loadBalancers:
       random:
         type: ROUND_ROBIN
   ```
   
   > server.yaml in ShardingSphere Proxy conf dir
   ```yml
   authority:
     users:
       - user: root@%
         password: Aa123456
       - user: sharding
         password: Aa123456
     privilege:
       type: ALL_PERMITTED
   props:
     sql-show: true
     check-table-metadata-enabled: true
     proxy-backend-query-fetch-size: -1
     proxy-mysql-default-version: 8.0.26 # In the absence of schema name, the 
default version will be used.
     proxy-default-port: 3333 # Proxy default port.
   ```
   
   That's all.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: 
[email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to