Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions .github/workflows/ci-spring-ydb.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: Spring YDB CI with Maven

on:
push:
paths:
- 'spring-ydb/**'
branches:
- main
pull_request:
paths:
- 'spring-ydb/**'

env:
MAVEN_ARGS: --batch-mode --update-snapshots -Dstyle.color=always

jobs:
prepare:
name: Prepare Maven cache
runs-on: ubuntu-24.04

env:
MAVEN_ARGS: --batch-mode -Dstyle.color=always

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: 'maven'

- name: Download dependencies (Default)
working-directory: ./spring-ydb
run: mvn $MAVEN_ARGS dependency:resolve-plugins dependency:go-offline

- name: Download dependencies (Spring Boot 3)
working-directory: ./spring-ydb
run: mvn $MAVEN_ARGS -Pspring-boot3 dependency:resolve-plugins dependency:go-offline

- name: Download dependencies (Spring Boot 4)
working-directory: ./spring-ydb
run: mvn $MAVEN_ARGS -Pspring-boot4 dependency:resolve-plugins dependency:go-offline

build:
name: Spring YDB build & tests
runs-on: ubuntu-24.04
needs: prepare

strategy:
matrix:
java: [ '17', '21', '24' ]

steps:
- uses: actions/checkout@v4

- name: Set up JDK ${{matrix.java}}
uses: actions/setup-java@v4
with:
java-version: ${{matrix.java}}
distribution: 'temurin'
cache: maven

- name: Build spring-ydb
working-directory: ./spring-ydb
run: mvn $MAVEN_ARGS package

- name: Tests with Spring Boot 3
working-directory: ./spring-ydb
run: mvn $MAVEN_ARGS -Pspring-boot3 test

- name: Tests with Spring Boot 4
working-directory: ./spring-ydb
run: mvn $MAVEN_ARGS -Pspring-boot4 test
82 changes: 82 additions & 0 deletions .github/workflows/publish-spring-ydb.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
name: Publish Spring YDB

on:
push:
tags:
- 'spring-ydb/v*.*.*'

env:
MAVEN_ARGS: --batch-mode --no-transfer-progress -Dstyle.color=always

jobs:
validate:
name: Validate Spring YDB
runs-on: ubuntu-24.04

steps:
- uses: actions/checkout@v4

- name: Extract spring-ydb version
run: |
cd spring-ydb
SPRING_YDB_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)
echo "SPRING_YDB_VERSION=$SPRING_YDB_VERSION" >> "$GITHUB_ENV"

- name: Fail workflow if version is snapshot
if: endsWith(env.SPRING_YDB_VERSION, 'SNAPSHOT')
uses: actions/github-script@v6
with:
script: core.setFailed('SNAPSHOT version cannot be published')

- name: Fail workflow if version is not equal to tag name
if: format('spring-ydb/v{0}', env.SPRING_YDB_VERSION) != github.ref_name
uses: actions/github-script@v6
with:
script: core.setFailed('Release name must be equal to project version')

- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: 17
distribution: 'temurin'
cache: 'maven'

- name: Download dependencies
working-directory: ./spring-ydb
run: mvn $MAVEN_ARGS -Pspring-boot-minimal dependency:go-offline

- name: Build with Maven
working-directory: ./spring-ydb
run: mvn $MAVEN_ARGS -Pspring-boot-minimal package

publish:
name: Publish Spring YDB
runs-on: ubuntu-latest
needs: validate

steps:
- name: Install gpg secret key
run: |
# Install gpg secret key
cat <(echo -e "${{ secrets.MAVEN_OSSRH_GPG_SECRET_KEY }}") | gpg --batch --import
# Verify gpg secret key
gpg --list-secret-keys --keyid-format LONG

- uses: actions/checkout@v4

- name: Set up Maven Central Repository
uses: actions/setup-java@v4
with:
java-version: 17
distribution: 'temurin'
cache: 'maven'
server-id: ossrh-s01
server-username: MAVEN_USERNAME
server-password: MAVEN_PASSWORD

- name: Publish package
working-directory: ./spring-ydb
run: mvn $MAVEN_ARGS -Possrh-s01,spring-boot-minimal -Dgpg.passphrase=${{ secrets.MAVEN_OSSRH_GPG_PASSWORD }} clean deploy
env:
MAVEN_USERNAME: ${{ secrets.MAVEN_OSSRH_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.MAVEN_OSSRH_TOKEN }}
142 changes: 142 additions & 0 deletions spring-ydb/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
<?xml version="1.0" encoding="UTF-8"?>
<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>tech.ydb</groupId>
<artifactId>spring-ydb</artifactId>
<version>1.0.0-SNAPSHOT</version>

<name>Spring YDB</name>
<description>Spring integration modules for YDB</description>
<url>https://github.com/ydb-platform/ydb-java-dialects</url>

<packaging>pom</packaging>

<developers>
<developer>
<name>Ekaterina Isaeva</name>
<email>ikaterina0909@gmail.com</email>
<organization>YDB</organization>
<organizationUrl>https://ydb.tech/</organizationUrl>
</developer>
<developer>
<name>Kirill Kurdyukov</name>
<email>kurdyukov-kir@ydb.tech</email>
<organization>YDB</organization>
<organizationUrl>https://ydb.tech/</organizationUrl>
</developer>
</developers>

<scm>
<url>https://github.com/ydb-platform/ydb-java-dialects</url>
<connection>scm:git:https://github.com/ydb-platform/ydb-java-dialects.git</connection>
<developerConnection>scm:git:https://github.com/ydb-platform/ydb-java-dialects.git</developerConnection>
</scm>

<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>

<modules>
<module>spring-ydb-retry</module>
</modules>

<properties>
<maven.compiler.release>17</maven.compiler.release>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<java.version>17</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>6.2.0</spring.version>
<spring-boot.version>3.4.0</spring-boot.version>
<ydb-jdbc.version>2.3.22</ydb-jdbc.version>
</properties>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>tech.ydb.jdbc</groupId>
<artifactId>ydb-jdbc-driver</artifactId>
<version>${ydb-jdbc.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

<profiles>
<profile>
<id>spring-boot-minimal</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<spring-boot.version>3.4.0</spring-boot.version>
</properties>
</profile>
<profile>
<id>spring-boot3</id>
<properties>
<spring-boot.version>3.5.7</spring-boot.version>
</properties>
</profile>
<profile>
<id>spring-boot4</id>
<properties>
<spring-boot.version>4.0.0</spring-boot.version>
</properties>
</profile>
<profile>
<id>ossrh-s01</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>3.2.7</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
<configuration>
<gpgArguments>
<arg>--pinentry-mode</arg>
<arg>loopback</arg>
</gpgArguments>
</configuration>
</plugin>
<plugin>
<groupId>org.sonatype.central</groupId>
<artifactId>central-publishing-maven-plugin</artifactId>
<version>0.7.0</version>
<extensions>true</extensions>
<configuration>
<publishingServerId>ossrh-s01</publishingServerId>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>

</project>
84 changes: 84 additions & 0 deletions spring-ydb/spring-ydb-retry/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Spring YDB Retry

## Overview

This project is a Spring Boot auto-configuration module that provides automatic retry
for transactional operations with [YDB](https://ydb.tech).

### Features

- Automatic retry of failed `@Transactional` methods on YDB retryable status codes
- `@YdbTransactional` annotation with per-method retry settings (maxRetries, backoff, idempotency)
- Dual backoff strategy (fast/slow) with jitter tailored to YDB error semantics
- Idempotent mode for extended retry coverage on non-deterministic status codes
- Fully configurable via `application.properties`

## Getting Started

### Requirements

- Java 21 or above
- Spring Boot 3.4+ / Spring Framework 6.2+
- [YDB JDBC Driver](https://github.com/ydb-platform/ydb-jdbc-driver)
- Access to a YDB Database instance

### Installation

For Maven, add the following dependency to your pom.xml:

```xml
<dependency>
<groupId>tech.ydb</groupId>
<artifactId>spring-ydb-retry</artifactId>
<!-- Set actual version -->
<version>${spring-ydb-retry.version}</version>
</dependency>
```

For Gradle, add the following to your build.gradle (or build.gradle.kts):

```groovy
dependencies {
implementation 'tech.ydb:spring-ydb-retry:$version' // Set actual version
}
```

## Usage

The module is auto-configured via Spring Boot. Once the dependency is on the classpath,
all `@Transactional` (and `@YdbTransactional`) methods are intercepted with retry logic.

### Annotation

Use `@YdbTransactional` as a drop-in replacement for `@Transactional` with additional
retry parameters:

```java
@YdbTransactional(maxRetries = 5, idempotent = true)
public void save(User user) {
// retried up to 5 times on YDB retryable errors
}
```

### Configuration

Configure retry behavior in `application.properties`:

```properties
# Enable/disable retry (default: true)
ydb.transaction.retry.enabled=true

# Maximum retry attempts (default: 10)
ydb.transaction.retry.max-retries=10

# Backoff settings for slow errors
ydb.transaction.retry.slow-backoff-base-ms=50
ydb.transaction.retry.slow-cap-backoff-ms=5000

# Backoff settings for fast errors
ydb.transaction.retry.fast-backoff-base-ms=5
ydb.transaction.retry.fast-cap-backoff-ms=500

```

Idempotent-only retry is configured per method via `@YdbTransactional(idempotent = true)`.
Loading
Loading