Skip to content
Merged
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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@
- Fixed broken links in `tarantool-spring-data/README.md` and `testcontainers/README.md`:
they pointed to `doc/` directories that do not exist and now point to the pages under
`documentation/doc-src/pages`.
- Documented that the spring-data `Repository` layer needs a cluster with `crud` and `vshard`,
and listed three ways to get one.
- Explained in the spring-data configuration example that `auth-type` must match
`security.auth_type` of the cluster and that `pap-sha256` requires Enterprise Edition and TLS.
- Added the "Limitations and workarounds" page: no batch delete and no `IN` condition in `crud`,
examples of parallel requests instead, and derived-method keywords that are not supported.
- Added a table that maps Spring Boot minor lines to `tarantool-spring-data-*` modules.

## [1.7.2] - 2026-09-25

Expand Down
67 changes: 67 additions & 0 deletions documentation/doc-src/pages/client/limitations.en.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
title: Limitations and workarounds
---

## What is not supported and how to work around it

The `crud` module on the Tarantool side has no batch delete (`delete_many`) and no `IN` condition:
conditions of a single `select` support only `==`, `<`, `<=`, `>`, `>=` and are combined by `AND`.
The client mirrors this: `TarantoolCrudSpace` has `insertMany`, `replaceMany` and `upsertMany`, but
no `deleteMany`. The workarounds below send several requests at once; requests of one client are
pipelined over its connections, so they do not wait for each other.

???+ warning "Important"

Neither workaround is atomic: each key is a separate operation, and keys can live on
different replica sets. Some requests may succeed while others fail; check every future.
The speed of these approaches relative to each other was not measured.

### Delete several records by primary key

```java
import java.util.List;
import java.util.concurrent.CompletableFuture;

import io.tarantool.client.crud.TarantoolCrudSpace;

CompletableFuture<?>[] futures =
keys.stream().map(space::delete).toArray(CompletableFuture[]::new);
CompletableFuture.allOf(futures).get();
```

In Spring Data, `deleteAllById(ids)` sends one request per key and waits for each response before
sending the next request.

Alternatively, write a stored procedure on the router that deletes the keys in a loop and call it with
`client.call(...)`: this is one network request from the application (also not atomic).

### Select by `col IN (v1, v2, v3)`

Send one `select` with the `==` condition per value in parallel and merge the results:

```java
import io.tarantool.client.crud.Condition;
import io.tarantool.mapping.Tuple;

List<CompletableFuture<List<Tuple<List<?>>>>> futures =
values.stream()
.map(v -> space.select(Condition.create("==", "col", v)))
.collect(Collectors.toList());
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).get();
List<Tuple<List<?>>> result = new ArrayList<>();
for (CompletableFuture<List<Tuple<List<?>>>> f : futures) {
result.addAll(f.get());
}
```

If `col` is the sharding key, each request goes to a single replica set; otherwise each `select` walks
all storages. For the primary key use `space.get(key)` for each key in parallel. Another option is
a stored procedure that takes the list of values and runs the selects on the server side.

### Spring Data derived methods

Supported keywords are listed in [Dynamic Queries](../spring-data/derived-methods.md). Keywords such
as `In`, `NotIn`, `Like` are not supported: such a method fails with
`InvalidDataAccessApiUsageException: Unsupported type ...`; a method with `And` or `Or` fails with
`UnsupportedOperationException`. Use the approaches above, or
[stored procedures](../spring-data/query-lua.md).
67 changes: 67 additions & 0 deletions documentation/doc-src/pages/client/limitations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
title: Ограничения и способы обхода
---

## Чего нет и как обойти

В модуле `crud` на стороне Tarantool нет пакетного удаления (`delete_many`) и условия `IN`:
условия одного `select` поддерживают только `==`, `<`, `<=`, `>`, `>=` и объединяются по `AND`.
Клиент это отражает: в `TarantoolCrudSpace` есть `insertMany`, `replaceMany`, `upsertMany`, но
нет `deleteMany`. Обходные пути ниже отправляют несколько запросов сразу; запросы одного клиента идут
конвейером по его соединениям и не ждут друг друга.

???+ warning "Важно"

Ни один из способов не атомарен: каждый ключ — отдельная операция, ключи могут лежать на разных
наборах реплик. Часть запросов может пройти, часть упасть; проверяйте каждый future.
Скорость способов друг относительно друга не измерялась.

### Удалить несколько записей по первичному ключу

```java
import java.util.List;
import java.util.concurrent.CompletableFuture;

import io.tarantool.client.crud.TarantoolCrudSpace;

CompletableFuture<?>[] futures =
keys.stream().map(space::delete).toArray(CompletableFuture[]::new);
CompletableFuture.allOf(futures).get();
```

В Spring Data `deleteAllById(ids)` отправляет по запросу на ключ и ждёт ответа на каждый, прежде
чем отправить следующий.

Другой путь: хранимая процедура на роутере, которая удаляет ключи в цикле, и вызов через
`client.call(...)` — один сетевой запрос от приложения (тоже не атомарно).

### Выборка `col IN (v1, v2, v3)`

Отправьте параллельно по одному `select` с условием `==` на каждое значение и склейте результат:

```java
import io.tarantool.client.crud.Condition;
import io.tarantool.mapping.Tuple;

List<CompletableFuture<List<Tuple<List<?>>>>> futures =
values.stream()
.map(v -> space.select(Condition.create("==", "col", v)))
.collect(Collectors.toList());
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).get();
List<Tuple<List<?>>> result = new ArrayList<>();
for (CompletableFuture<List<Tuple<List<?>>>> f : futures) {
result.addAll(f.get());
}
```

Если `col` — ключ шардирования, каждый запрос идёт в один набор реплик; иначе каждый `select` обходит
все хранилища. Для первичного ключа — `space.get(key)` по каждому ключу параллельно. Ещё вариант —
хранимая процедура, принимающая список значений и выполняющая выборки на стороне сервера.

### Производные методы Spring Data

Поддерживаемые ключевые слова перечислены в [Динамические запросы](../spring-data/derived-methods.md).
Ключевые слова `In`, `NotIn`, `Like` не поддерживаются: такой метод завершается ошибкой
`InvalidDataAccessApiUsageException: Unsupported type ...`; метод с `And` или `Or` завершается
`UnsupportedOperationException`. Используйте подходы выше или
[хранимые процедуры](../spring-data/query-lua.md).
6 changes: 5 additions & 1 deletion documentation/doc-src/pages/spring-data/configuration.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,11 @@ To configure the client through a configuration file (for example, via
8. Time in ms after which to reconnect upon failed connection
(`reconnect-after: 1000` - 1 second)
9. Sets a list of connection groups with descriptions of each
10. Authentication protocol type
10. Authentication protocol type. It must match the method the user's password is stored with,
i.e. `security.auth_type` (`box.cfg.auth_type`) of the cluster; otherwise the login fails with
`User not found or supplied credentials are invalid`. The default is `chap-sha1`, and it is
also the client default, so the parameter can be omitted. `pap-sha256` is available only in
Enterprise Edition (and TDB) and only over an encrypted (TLS) connection
11. The address to which the client connects
12. The port to which the client connects on `host`
13. The username for connecting to `Tarantool`
Expand Down
6 changes: 5 additions & 1 deletion documentation/doc-src/pages/spring-data/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,11 @@ public class Config {
8. Время в мс, через которое необходимо сделать пересоединение при неудачном подключении
(`reconnect-after: 1000` - 1 секунда)
9. Задает список групп подключения с описанием каждой из них
10. Тип протокола аутентификации
10. Тип протокола аутентификации. Должен совпадать с методом, которым хранится пароль
пользователя, то есть с `security.auth_type` (`box.cfg.auth_type`) кластера; иначе вход
завершится ошибкой `User not found or supplied credentials are invalid`. По умолчанию
`chap-sha1` — это же умолчание клиента, параметр можно не указывать. `pap-sha256` доступен
только в Enterprise Edition (и TDB) и только по шифрованному (TLS) соединению
11. Адрес, к которому подключается клиент
12. Порт, к которому подключается клиент на `host`
13. Имя пользователя для подключения к `Tarantool`
Expand Down
5 changes: 5 additions & 0 deletions documentation/doc-src/pages/spring-data/derived-methods.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ public interface PersonRepository extends PagingAndSortingRepository<Person, Int
Currently, only methods with a single predicate are supported (nested `AND` or
`OR` are not supported).

Any keyword not listed above (for example `In`, `NotIn`, `Like`) is not supported and fails with
`InvalidDataAccessApiUsageException: Unsupported type ...`; a method with `And` or `Or` fails with
`UnsupportedOperationException`.
Workarounds: [Limitations and workarounds](../client/limitations.md).

???+ note "Note"

In version tarantool-spring-data32, the ability to use the [Limit](https://docs.spring.io/spring-data/data-commons/docs/3.2.3/api/org/springframework/data/domain/Limit.html)
Expand Down
5 changes: 5 additions & 0 deletions documentation/doc-src/pages/spring-data/derived-methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ public interface PersonRepository extends PagingAndSortingRepository<Person, Int
На данный момент поддерживаются только методы с одним предикатом (не поддерживаются `AND` или
`OR`).

Любое ключевое слово вне списка выше (например, `In`, `NotIn`, `Like`) не поддерживается и
приводит к `InvalidDataAccessApiUsageException: Unsupported type ...`; метод с `And` или `Or`
завершается `UnsupportedOperationException`.
Способы обхода: [Ограничения и способы обхода](../client/limitations.md).

???+ note "Заметка"

В версию tarantool-spring-data32 добавлена возможность использовать в производных методах
Expand Down
29 changes: 29 additions & 0 deletions documentation/doc-src/pages/spring-data/index.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,20 @@ using [Tarantool](https://www.tarantool.io) as a data store.
| 1.6.x | 1.6.x | 2.7.18 / 3.1.12 / 3.2.12 / 3.3.13 / 3.4.13 / 3.5.8 |
| 1.7.x | 1.7.x | 2.7.18 / 3.1.12 / 3.2.12 / 3.3.13 / 3.4.13 / 3.5.13 / 4.0.6 |

Choose the module by the Spring Boot minor line of your application. The table above lists the
Spring Boot versions each module is built and tested with; other patch versions of the same line are
not tested in CI, and newer minor lines are not tested at all.

| Spring Boot line | Module |
|:----------------:|:---------------------------:|
| 2.7.x | `tarantool-spring-data-27` |
| 3.1.x | `tarantool-spring-data-31` |
| 3.2.x | `tarantool-spring-data-32` |
| 3.3.x | `tarantool-spring-data-33` |
| 3.4.x | `tarantool-spring-data-34` |
| 3.5.x | `tarantool-spring-data-35` |
| 4.0.x | `tarantool-spring-data-40` |

### Tarantool Version and Supported Client Modules

| Tarantool Version | CRUD API (cluster) | BOX API (single instance) |
Expand Down Expand Up @@ -58,6 +72,21 @@ To work with the module, access to a running Tarantool is required. Instructions
Tarantool can be found
here: [`github`](https://github.com/tarantool/tarantool?tab=readme-ov-file#tarantool).

???+ warning "Cluster with `crud` and `vshard` is required for `Repository`"

The repository layer (`@EnableTarantoolRepositories`) is bound to `TarantoolCrudClient` and calls
the `crud.*` stored procedures, which are provided by the [`crud`](https://github.com/tarantool/crud)
module on top of `vshard`. A plain `tarantool/tarantool` image from Docker Hub has neither of them,
so `Repository` calls fail with `Procedure 'crud.select' is not defined`.
Run a cluster (a router with `crud` and storages with `vshard`), using one of the following ways:

- an image of Tarantool DB (TDB), which already includes `crud` and `vshard`;
- the [tarantool-java-sdk/testcontainers](../testcontainers/tdb/index.md) module, which starts
a TDB cluster from a test;
- your own image: an example based on `tarantool/tarantool` with the `crud` rock and the
`router.lua`/`storage.lua` scripts is in the repository, directory
`tarantool-shared-resources/vshard_cluster`.

???+ warning "Important"

- This module is designed to work with Tarantool versions `2.11.x` and `3.x`. Differences between versions
Expand Down
29 changes: 29 additions & 0 deletions documentation/doc-src/pages/spring-data/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,20 @@ hide:
| 1.6.x | 1.6.x | 2.7.18 / 3.1.12 / 3.2.12 / 3.3.13 / 3.4.13 / 3.5.8 |
| 1.7.x | 1.7.x | 2.7.18 / 3.1.12 / 3.2.12 / 3.3.13 / 3.4.13 / 3.5.13 / 4.0.6 |

Модуль выбирается по минорной линии Spring Boot приложения. В таблице выше — версии Spring Boot, с
которыми модули собраны и протестированы; другие патч-версии той же линии в CI не проверяются, более
новые минорные линии не проверяются вовсе.

| Линия Spring Boot | Модуль |
|:-----------------:|:---------------------------:|
| 2.7.x | `tarantool-spring-data-27` |
| 3.1.x | `tarantool-spring-data-31` |
| 3.2.x | `tarantool-spring-data-32` |
| 3.3.x | `tarantool-spring-data-33` |
| 3.4.x | `tarantool-spring-data-34` |
| 3.5.x | `tarantool-spring-data-35` |
| 4.0.x | `tarantool-spring-data-40` |

### Версия Tarantool и поддерживаемые модули-клиенты

| Версия Tarantool | CRUD API (кластер) | BOX API (один экземпляр) |
Expand Down Expand Up @@ -58,6 +72,21 @@ hide:
Tarantool можно найти
здесь: [`github`](https://github.com/tarantool/tarantool?tab=readme-ov-file#tarantool).

???+ warning "Для `Repository` нужен кластер с `crud` и `vshard`"

Слой репозиториев (`@EnableTarantoolRepositories`) привязан к `TarantoolCrudClient` и вызывает
хранимые процедуры `crud.*`, которые даёт модуль [`crud`](https://github.com/tarantool/crud)
поверх `vshard`. В обычном образе `tarantool/tarantool` с Docker Hub нет ни того, ни другого,
поэтому вызовы `Repository` завершаются ошибкой `Procedure 'crud.select' is not defined`.
Поднимите кластер (роутер с `crud` и хранилища с `vshard`) одним из способов:

- образ Tarantool DB (TDB): `crud` и `vshard` в нём уже есть;
- модуль [tarantool-java-sdk/testcontainers](../testcontainers/tdb/index.md): запускает кластер
TDB из теста;
- собственный образ: пример на основе `tarantool/tarantool` с рокспеком `crud` и скриптами
`router.lua`/`storage.lua` лежит в репозитории, каталог
`tarantool-shared-resources/vshard_cluster`.

???+ warning "Важно"

- Данный модуль рассчитан на работу с Tarantool версий `2.11.x` и `3.x` . С отличиями версий
Expand Down
1 change: 1 addition & 0 deletions documentation/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ nav:
- Хранимые процедуры:
- pages/client/examples/call/index.md
- pages/client/examples/call/call.md
- pages/client/limitations.md
- Tarantool Testcontainers:
- pages/testcontainers/index.md
- Одиночный узел:
Expand Down
14 changes: 14 additions & 0 deletions tarantool-spring-data/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,20 @@ data storage.
| 1.6.x | 1.6.x | 2.7.18 / 3.1.12 / 3.2.12 / 3.3.13 / 3.4.13 / 3.5.8 |
| 1.7.x | 1.7.x | 2.7.18 / 3.1.12 / 3.2.12 / 3.3.13 / 3.4.13 / 3.5.13 / 4.0.6 |

Choose the module by the Spring Boot minor line of your application. The table above lists the
Spring Boot versions each module is built and tested with; other patch versions of the same line are
not tested in CI, and newer minor lines are not tested at all.

| Spring Boot line | Module |
|:----------------:|:---------------------------:|
| 2.7.x | `tarantool-spring-data-27` |
| 3.1.x | `tarantool-spring-data-31` |
| 3.2.x | `tarantool-spring-data-32` |
| 3.3.x | `tarantool-spring-data-33` |
| 3.4.x | `tarantool-spring-data-34` |
| 3.5.x | `tarantool-spring-data-35` |
| 4.0.x | `tarantool-spring-data-40` |

### Tarantool Version and Supported Client Modules

| Tarantool Version | CRUD API (cluster) | BOX API (single instance) |
Expand Down