MySplitter
[中文] [GitHub] [Apache License 2.0]
MySplitter is a lightweight JDBC middleware for read/write splitting, multiple data sources, high availability, load balancing, and routed database connections.
The current release line is 1.1.0. It keeps the production default safe with local JDBC transactions, while introducing a gated experimental XA transaction MVP for teams validating distributed transactions across multiple database brands.
What MySplitter Helps With
- Route SQL to different logical databases from one
DataSource. - Split read and write traffic across reader and writer nodes.
- Reuse routed physical connections inside one logical JDBC connection.
- Pin transaction traffic to writer routes when transaction semantics require it.
- Fail over unhealthy datasource nodes and retry recovery after a configured interval.
- Execute datasource filters for every routed SQL, including reused and transaction-pinned routes.
- Expose datasource status through
MySplitterDataSource#getStatus(). - Load configuration from YAML safely.
- Use explicit password source modes for local development and production deployment.
- Integrate with Spring Boot
2.7.xthroughmysplitter-spring-boot-starter.
Release Status
| Area | Status |
|---|---|
| Latest release | 1.1.0 |
| Java baseline | Java 8+ |
| Spring Boot starter | Spring Boot 2.7.x |
| Primary pool baseline | HikariCP |
| Configuration format | YAML |
| Production transaction mode | local |
| Experimental transaction mode | xa, gated by mysplitter.experimental.xa.enabled=true |
Core Features
- Multiple datasource nodes across one or more logical databases.
- Read/write separation with conservative default SQL classification.
- Database routing and optional SQL rewriting through user-defined routing advice.
- Load balancing with polling or weighted random strategies.
- High availability with ill-node tracking and recovery checks.
- Safe YAML loading through SnakeYAML safe construction.
- Password modes:
plainfor local development convenience.environmentfor system property or environment-backed deployment secrets.legacy-rsafor backward compatibility only.
- Spring Boot starter metadata for both
spring.factoriesandAutoConfiguration.imports. - Experimental XA foundation with file transaction logs and recovery execution.
Experimental XA In 1.1.0
XA support is available for development validation, but it is not the production default yet.
What is implemented:
- Transaction SPI and embedded transaction coordinator.
- XA branch enlistment through
XADataSource. - Two-phase prepare, commit, and rollback.
- Append-only file transaction log store.
- Durable commit / rollback decisions.
- XA recovery executor using
XAResource.recover(...). - H2 routed XA lifecycle coverage.
- MySQL and PostgreSQL prepared-branch recovery coverage with Testcontainers.
- PostgreSQL database-unavailable recovery failure coverage.
Important caveats:
- Enable XA only with
-Dmysplitter.experimental.xa.enabled=true. - Keep
transaction.mode: localfor production unless you explicitly accept the experimental contract. - Use
transaction.coordinator.logStore: filefor durable recovery validation. - PostgreSQL requires
max_prepared_transactions > 0. - Admin APIs, metrics, and multi-process coordinator fencing are not implemented yet.
Maven Coordinates
Core library:
<dependency>
<groupId>com.mysplitter</groupId>
<artifactId>mysplitter</artifactId>
<version>1.1.0</version>
</dependency>
Spring Boot starter:
<dependency>
<groupId>com.mysplitter</groupId>
<artifactId>mysplitter-spring-boot-starter</artifactId>
<version>1.1.0</version>
</dependency>
Spring Boot Quick Start
application.yml
spring:
datasource:
mysplitter:
configuration-file: classpath:mysplitter.yml
mysplitter.yml
mysplitter:
passwordSource: environment
databasesRoutingHandler: com.example.DatabaseRouter
readAndWriteParser: com.example.ReadAndWriteParser
illAlertHandler: com.example.DataSourceIllAlertHandler
common:
dataSourceClass: com.zaxxer.hikari.HikariDataSource
loadBalance:
read:
enabled: true
strategy: polling
failTimeout: 30s
write:
enabled: true
strategy: polling
failTimeout: 30s
databases:
database-a:
readers:
reader-1:
configuration:
jdbcUrl: jdbc:mysql://localhost:3306/user
username: ${DB_USER}
password: ${DB_PASSWORD}
driverClassName: com.mysql.cj.jdbc.Driver
connectionTimeout: 1000
writers:
writer-1:
configuration:
jdbcUrl: jdbc:mysql://localhost:3306/user
username: ${DB_USER}
password: ${DB_PASSWORD}
driverClassName: com.mysql.cj.jdbc.Driver
connectionTimeout: 1000
For local development, passwordSource: plain is also supported when you intentionally want to keep credentials in a local configuration file.
Experimental XA Configuration Preview
mysplitter:
transaction:
mode: xa
coordinator:
type: embedded
logStore: file
logFile: ./target/mysplitter-xa.log
recovery:
enabled: true
interval: 10s
databases:
database-a:
writers:
writer-1:
configuration:
jdbcUrl: jdbc:mysql://127.0.0.1:3306/app
username: ${DB_USER}
password: ${DB_PASSWORD}
driverClassName: com.mysql.cj.jdbc.Driver
xaDataSourceClass: com.mysql.jdbc.jdbc2.optional.MysqlXADataSource
xaProperties:
url: jdbc:mysql://127.0.0.1:3306/app?useSSL=false
user: ${DB_USER}
password: ${DB_PASSWORD}
Run with:
java -Dmysplitter.experimental.xa.enabled=true ...
Documentation In The Repository
- Release notes
- Verification commands
- v1.0 compatibility matrix
- v1.1 XA compatibility matrix
- v1.1 XA operations notes
Project Direction
1.1.x: gated experimental XA MVP and transaction foundation.1.2.x: broader heterogeneous XA compatibility and failure-recovery matrix.1.3.x: AT-style automatic compensation for selected relational database dialects.1.4.x: TCC and Saga extension points for resources that cannot safely use XA or AT.