diff options
author | alexandr268 <alexandr268@yandex-team.ru> | 2022-04-06 21:52:40 +0300 |
---|---|---|
committer | alexandr268 <alexandr268@yandex-team.ru> | 2022-04-06 21:52:40 +0300 |
commit | bcc94a11eb3b4cd7f8c80f5eb4b5e5eb832f74fc (patch) | |
tree | de4672a6642c1fd81baea293634006527e2d0908 | |
parent | 3b53fc30368aa56b2cdcfeaf8215cbc680fce307 (diff) | |
download | ydb-bcc94a11eb3b4cd7f8c80f5eb4b5e5eb832f74fc.tar.gz |
Update Java SDK example and documentation KIKIMR-14232
Add run options for Java SDK example
Update Java SDK example documentation
Update simple project
Fix broken link to cpp example
Update simple project example
Update basic example
ref:287f21d20bb80e5667f2c8f295c06dab0ed351ae
10 files changed, 430 insertions, 12 deletions
diff --git a/ydb/docs/ru/core/getting_started/_includes/sdk.md b/ydb/docs/ru/core/getting_started/_includes/sdk.md index 5aabebc2b2..93fe95d9cb 100644 --- a/ydb/docs/ru/core/getting_started/_includes/sdk.md +++ b/ydb/docs/ru/core/getting_started/_includes/sdk.md @@ -10,5 +10,6 @@ * [Python](../../reference/ydb-sdk/example/python/index.md) * [Go](../../reference/ydb-sdk/example/go/index.md) + * [Java](../../reference/ydb-sdk/example/java/index.md) Полная информация о {{ ydb-short-name }} SDK находится в разделе [Работа с {{ ydb-short-name }} SDK](../../reference/ydb-sdk/index.md). diff --git a/ydb/docs/ru/core/reference/ydb-sdk/example/_includes/index.md b/ydb/docs/ru/core/reference/ydb-sdk/example/_includes/index.md index fa5a4b70ab..46bade084c 100644 --- a/ydb/docs/ru/core/reference/ydb-sdk/example/_includes/index.md +++ b/ydb/docs/ru/core/reference/ydb-sdk/example/_includes/index.md @@ -7,7 +7,7 @@ {% endif %} - [С# (.NET)](../example-dotnet.md) - [Go](../go/index.md) -- [Java](../example-java.md) +- [Java](../java/index.md) - [Node.js](../example-nodejs.md) - [Python](../python/index.md) @@ -15,35 +15,35 @@ {% include [init.md](steps/01_init.md) %} -{% if oss %}[C++](../example-cpp.md#init) | {% endif %} [C# (.NET)](../example-dotnet.md#init) | [Go](../go/index.md#init) | [Java](../example-java.md#init) | Node.js | [PHP](../example-php.md#init) | [Python](../python/index.md#init) +{% if oss %}[C++](../example-cpp.md#init) | {% endif %} [C# (.NET)](../example-dotnet.md#init) | [Go](../go/index.md#init) | [Java](../java/index.md#init) | Node.js | [PHP](../example-php.md#init) | [Python](../python/index.md#init) {% include [create_table.md](steps/02_create_table.md) %} -{% if oss %}[C++](../example-cpp.md#create-table) | {% endif %} [C# (.NET)](../example-dotnet.md#create-table) | [Go](../go/index.md#create-table) | [Java](../example-java.md#create-table) | Node.js | PHP | [Python](../python/index.md#create-table) +{% if oss %}[C++](../example-cpp.md#create-table) | {% endif %} [C# (.NET)](../example-dotnet.md#create-table) | [Go](../go/index.md#create-table) | [Java](../java/index.md#create-table) | Node.js | PHP | [Python](../python/index.md#create-table) {% include [write_queries.md](steps/03_write_queries.md) %} -{% if oss %}[C++](../example-cpp.md#write-queries) | {% endif %} [C# (.NET)](../example-dotnet.md#write-queries) | Go | [Java](../example-java.md#write-queries) | Node.js | PHP | [Python](../python/index.md#write-queries) +{% if oss %}[C++](../example-cpp.md#write-queries) | {% endif %} [C# (.NET)](../example-dotnet.md#write-queries) | Go | [Java](../java/index.md#write-queries) | Node.js | PHP | [Python](../python/index.md#write-queries) {% include [query_processing.md](steps/04_query_processing.md) %} -{% if oss %}[C++](../example-cpp.md#query-processing) | {% endif %} [C# (.NET)](../example-dotnet.md#query-processing) | [Go](../go/index.md#query-processing) | [Java](../example-java.md#query-processing) | Node.js | PHP | [Python](../python/index.md#query-processing) +{% if oss %}[C++](../example-cpp.md#query-processing) | {% endif %} [C# (.NET)](../example-dotnet.md#query-processing) | [Go](../go/index.md#query-processing) | [Java](../java/index.md#query-processing) | Node.js | PHP | [Python](../python/index.md#query-processing) {% include [param_queries.md](steps/06_param_queries.md) %} -{% if oss %}[C++](../example-cpp.md#param-queries) | {% endif %} [C# (.NET)](../example-dotnet.md#param-queries) | [Go](../go/index.md#param-queries) | [Java](../example-java.md#param-queries) | Node.js | PHP | [Python](../python/index.md#param-queries) +{% if oss %}[C++](../example-cpp.md#param-queries) | {% endif %} [C# (.NET)](../example-dotnet.md#param-queries) | [Go](../go/index.md#param-queries) | [Java](../java/index.md#param-queries) | Node.js | PHP | [Python](../python/index.md#param-queries) {% include [scan_query.md](steps/08_scan_query.md) %} -{% if oss %}C++ | {% endif %} [C# (.NET)](../example-dotnet.md#scan-query) | [Go](../go/index.md#scan-query) | [Java](../example-java.md#scan-query) | [Node.js](../example-nodejs.md#scan-query) | PHP | [Python](../python/index.md#scan-query) +{% if oss %}C++ | {% endif %} [C# (.NET)](../example-dotnet.md#scan-query) | [Go](../go/index.md#scan-query) | [Java](../java/index.md#scan-query) | [Node.js](../example-nodejs.md#scan-query) | PHP | [Python](../python/index.md#scan-query) {% include [multistep_transactions.md](steps/09_multistep_transactions.md) %} -{% if oss %}[C++](../example-cpp.md#multistep-transactions) | {% endif %} C# (.NET) | Go | [Java](../example-java.md#multistep-transactions) | Node.js | PHP | Python +{% if oss %}[C++](../example-cpp.md#multistep-transactions) | {% endif %} C# (.NET) | Go | [Java](../java/index.md#multistep-transactions) | Node.js | PHP | Python {% include [transaction_control.md](steps/10_transaction_control.md) %} -{% if oss %}[C++](../example-cpp.md#tcl) | {% endif %} C# (.NET) | Go | [Java](../example-java.md#tcl) | Node.js | PHP | [Python](../python/index.md#tcl) +{% if oss %}[C++](../example-cpp.md#tcl) | {% endif %} C# (.NET) | Go | [Java](../java/index.md#tcl) | Node.js | PHP | [Python](../python/index.md#tcl) {% include [error_handling.md](steps/50_error_handling.md) %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/example/example-java.md b/ydb/docs/ru/core/reference/ydb-sdk/example/example-java.md deleted file mode 100644 index 3306908cf9..0000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/example/example-java.md +++ /dev/null @@ -1,2 +0,0 @@ -{% include [example-java.md](_includes/example-java.md) %} - diff --git a/ydb/docs/ru/core/reference/ydb-sdk/example/java/_includes/run_custom.md b/ydb/docs/ru/core/reference/ydb-sdk/example/java/_includes/run_custom.md new file mode 100644 index 0000000000..79c5d1f0c8 --- /dev/null +++ b/ydb/docs/ru/core/reference/ydb-sdk/example/java/_includes/run_custom.md @@ -0,0 +1,23 @@ +Для выполнения примера с использованием любой доступной базы данных YDB вам потребуется знать [Эндпоинт](../../../../../concepts/connect.md#endpoint) и [Размещение базы данных](../../../../../concepts/connect.md#database). + +Если в базе данных включена аутентификация, то вам также понадобится выбрать [режим аутентификации](../../../../../concepts/connect.md#auth-modes) и получить секреты - токен или логин/пароль. + +Выполните команду по следующему образцу: + +``` bash +<auth_mode_var>="<auth_mode_value>" java -jar examples/simple_project/target/ydb-simple-project.jar <endpoint>?database=<database> +``` + +, где + +- `<endpoint>` - [Эндпоинт](../../../../../concepts/connect.md#endpoint) +- `<database>` - [Размещение базы данных](../../../../../concepts/connect.md#database) +- `<auth_mode_var`> - [Переменная окружения](../../../auth.md#env), определяющая режим аутентификации +- `<auth_mode_value>` - Значение параметра аутентификации для выбранного режима + +Например: +``` bash +YDB_ACCESS_TOKEN_CREDENTIALS="t1.9euelZqOnJuJlc..." java -jar examples/simple_project/target/ydb-simple-project.jar grpcs://ydb.example.com:2135?database=/somepath/somelocation +``` + +{% include [../../_includes/pars_from_profile_hint.md](../../_includes/pars_from_profile_hint.md) %}
\ No newline at end of file diff --git a/ydb/docs/ru/core/reference/ydb-sdk/example/java/_includes/run_docker.md b/ydb/docs/ru/core/reference/ydb-sdk/example/java/_includes/run_docker.md new file mode 100644 index 0000000000..4abdddb1cb --- /dev/null +++ b/ydb/docs/ru/core/reference/ydb-sdk/example/java/_includes/run_docker.md @@ -0,0 +1,5 @@ +Для соединения с развернутой локальной базой данных YDB по сценарию [Docker](../../../../../getting_started/self_hosted/ydb_docker.md) в конфигурации по умолчанию выполните следующую команду: + +``` bash +YDB_ANONYMOUS_CREDENTIALS=1 java -jar examples/simple_project/target/ydb-simple-project.jar grpc://localhost:2136?database=/local +``` diff --git a/ydb/docs/ru/core/reference/ydb-sdk/example/java/_includes/run_options.md b/ydb/docs/ru/core/reference/ydb-sdk/example/java/_includes/run_options.md new file mode 100644 index 0000000000..a637c6126b --- /dev/null +++ b/ydb/docs/ru/core/reference/ydb-sdk/example/java/_includes/run_options.md @@ -0,0 +1,11 @@ +{% list tabs %} + +- Local Docker + + {% include [run_docker.md](run_docker.md) %} + +- Любая база данных + + {% include [run_custom.md](run_custom.md) %} + +{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/example/java/index.md b/ydb/docs/ru/core/reference/ydb-sdk/example/java/index.md new file mode 100644 index 0000000000..89135d2f42 --- /dev/null +++ b/ydb/docs/ru/core/reference/ydb-sdk/example/java/index.md @@ -0,0 +1,369 @@ +# Приложение на Java + +На этой странице подробно разбирается код [тестового приложения](https://github.com/yandex-cloud/ydb-java-sdk/tree/master/examples/simple_project), доступного в составе [Java SDK](https://github.com/yandex-cloud/ydb-java-sdk) {{ ydb-short-name }}. + +## Скачивание SDK и запуск примера {#download} + +Приведенный ниже сценарий запуска использует [git](https://git-scm.com/downloads) и [Maven](https://maven.apache.org/download.html). + +Создайте рабочую директорию и выполните в ней из командной строки команду клонирования репозитория с github.com: + +``` bash +git clone https://github.com/yandex-cloud/ydb-java-sdk +``` + +Далее выполните сборку SDK и входящих в него примеров + +``` bash +cd ydb-java-sdk && mvn clean package +``` + +Далее из этой же рабочей директории выполните команду запуска тестового приложения, которая будет отличаться в зависимости от того, к какой базе данных необходимо подключиться. + +{% include [run_options.md](_includes/run_options.md) %} + + +{% include [init.md](../_includes/steps/01_init.md) %} + +Основные параметры инициализации драйвера +* Cтрока подключения с информацией об [эндпоинте](../../../../concepts/connect.md#endpoint) и [базе данных](../../../../concepts/connect.md#database). Единственный обязательные параметр. +* Провайдер [аутенфикации](../../auth.md##auth-provider). В случае отсутсвия прямого указания - будет использоваться [анонимное подключение](../../../../concepts/connect.md#auth-modes). +* Настройки [пула сессий](../../recipes/session_pool_limit/index.md) + +Фрагмент кода приложения для инициализации драйвера: + +```java +GrpcTransport transport = GrpcTransport.forConnectionString(connectionString) + .withAuthProvider(CloudAuthHelper.getAuthProviderFromEnviron()) + .build(); +GrpcTableRpc rpc = GrpcTableRpc.ownTransport(transport); +this.tableClient = TableClient.newClient(rpc).build(); +``` + +Все операции с YDB рекомендуется выполнять с помощью класса-хелпера `SessionRetryContext`, который обеспечивает корректное повтороное выполнение операция в случае частичной недоступности. Фрагмент кода для инициализации контекста ретраев: + +```java +this.retryCtx = SessionRetryContext.create(tableClient).build(); +``` + +{% include [create_table.md](../_includes/steps/02_create_table.md) %} + +Для создания таблиц используется метод `Session.createTable()`: + +```java +private void createTables() { + TableDescription seriesTable = TableDescription.newBuilder() + .addNullableColumn("series_id", PrimitiveType.uint64()) + .addNullableColumn("title", PrimitiveType.utf8()) + .addNullableColumn("series_info", PrimitiveType.utf8()) + .addNullableColumn("release_date", PrimitiveType.date()) + .setPrimaryKey("series_id") + .build(); + + retryCtx.supplyStatus(session -> session.createTable(database + "/series", seriesTable)) + .join().expect("create table problem"); + + TableDescription seasonsTable = TableDescription.newBuilder() + .addNullableColumn("series_id", PrimitiveType.uint64()) + .addNullableColumn("season_id", PrimitiveType.uint64()) + .addNullableColumn("title", PrimitiveType.utf8()) + .addNullableColumn("first_aired", PrimitiveType.date()) + .addNullableColumn("last_aired", PrimitiveType.date()) + .setPrimaryKeys("series_id", "season_id") + .build(); + + retryCtx.supplyStatus(session -> session.createTable(database + "/seasons", seasonsTable)) + .join().expect("create table problem"); + + TableDescription episodesTable = TableDescription.newBuilder() + .addNullableColumn("series_id", PrimitiveType.uint64()) + .addNullableColumn("season_id", PrimitiveType.uint64()) + .addNullableColumn("episode_id", PrimitiveType.uint64()) + .addNullableColumn("title", PrimitiveType.utf8()) + .addNullableColumn("air_date", PrimitiveType.date()) + .setPrimaryKeys("series_id", "season_id", "episode_id") + .build(); + + retryCtx.supplyStatus(session -> session.createTable(database + "/episodes", episodesTable)) + .join().expect("create table problem"); +} +``` + +С помощью метода `Session.describeTable()` можно вывести информацию о структуре таблицы и убедиться, что она успешно создалась: + +```java +private void describeTables() { + logger.info("--[ DescribeTables ]--"); + + Arrays.asList("series", "seasons", "episodes").forEach(tableName -> { + String tablePath = database + '/' + tableName; + TableDescription tableDesc = retryCtx.supplyResult(session -> session.describeTable(tablePath)) + .join().expect("describe table problem"); + + List<String> primaryKeys = tableDesc.getPrimaryKeys(); + logger.info(" table {}", tableName); + for (TableColumn column : tableDesc.getColumns()) { + boolean isPrimary = primaryKeys.contains(column.getName()); + logger.info(" {}: {} {}", column.getName(), column.getType(), isPrimary ? " (PK)" : ""); + } + }); +} +``` +{% include [../steps/03_write_queries.md](../_includes/steps/03_write_queries.md) %} + +Фрагмент кода, демонстрирующий выполнение запроса на запись/изменение данных: + +```java +private void upsertSimple() { + String query + = "UPSERT INTO episodes (series_id, season_id, episode_id, title) " + + "VALUES (2, 6, 1, \"TBD\");"; + + // Begin new transaction with SerializableRW mode + TxControl txControl = TxControl.serializableRw().setCommitTx(true); + + // Executes data query with specified transaction control settings. + retryCtx.supplyResult(session -> session.executeDataQuery(query, txControl)) + .join().expect("execute data query problem"); +} +``` + +{% include [steps/04_query_processing.md](../_includes/steps/04_query_processing.md) %} + +Для выполнения YQL-запросов используется метод `Session.executeDataQuery()`. +SDK позволяет в явном виде контролировать выполнение транзакций и настраивать необходимый режим выполнения транзакций с помощью класса `TxControl`. + +В фрагменте кода, приведенного ниже, транзакция выполняется с помощью метода `session.executeDataQuery()`. Устанавливается режим выполнения транзакции `TxControl txControl = TxControl.serializableRw().setCommitTx(true);` и флаг автоматического завершения транзакции `setCommitTx(true)`. Тело запроса описано с помощью синтаксиса YQL и как параметр передается методу `executeDataQuery`. + +```java +private void selectSimple() { + String query + = "SELECT series_id, title, release_date " + + "FROM series WHERE series_id = 1;"; + + // Begin new transaction with SerializableRW mode + TxControl txControl = TxControl.serializableRw().setCommitTx(true); + + // Executes data query with specified transaction control settings. + DataQueryResult result = retryCtx.supplyResult(session -> session.executeDataQuery(query, txControl)) + .join().expect("execute data query"); + + logger.info("--[ SelectSimple ]--"); + + ResultSetReader rs = result.getResultSet(0); + while (rs.next()) { + logger.info("read series with id {}, title {} and release_date {}", + rs.getColumn("series_id").getUint64(), + rs.getColumn("title").getUtf8(), + rs.getColumn("release_date").getDate() + ); + } +} +``` + +В результате исполнения запроса формируется объект класса `DataQueryResult`, который может содержать несколько выборок, получаемых методом `getResultSet( <index> )`. Так как запрос содержал только одну команду `SELECT`, то результат содержит только одну выборку под индексом `0`. Приведенный фрагмент кода при запуске выводит на консоль текст: + +```bash +12:06:36.548 INFO App - --[ SelectSimple ]-- +12:06:36.559 INFO App - read series with id 1, title IT Crowd and release_date 2006-02-03 +``` + +{% include [param_queries.md](../_includes/steps/06_param_queries.md) %} + +Фрагмент кода, приведенный ниже, демонстрирует использование параметризованных запросов и класс `Params` для формирования параметров и передачи их методу `executeDataQuery`. + +```java +private void selectWithParams(long seriesID, long seasonID) { + String query + = "DECLARE $seriesId AS Uint64; " + + "DECLARE $seasonId AS Uint64; " + + "SELECT sa.title AS season_title, sr.title AS series_title " + + "FROM seasons AS sa INNER JOIN series AS sr ON sa.series_id = sr.series_id " + + "WHERE sa.series_id = $seriesId AND sa.season_id = $seasonId"; + + // Begin new transaction with SerializableRW mode + TxControl txControl = TxControl.serializableRw().setCommitTx(true); + + // Type of parameter values should be exactly the same as in DECLARE statements. + Params params = Params.of( + "$seriesId", PrimitiveValue.uint64(seriesID), + "$seasonId", PrimitiveValue.uint64(seasonID) + ); + + DataQueryResult result = retryCtx.supplyResult(session -> session.executeDataQuery(query, txControl, params)) + .join().expect("execute data query"); + + logger.info("--[ SelectWithParams ] -- "); + + ResultSetReader rs = result.getResultSet(0); + while (rs.next()) { + logger.info("read season with title {} for series {}", + rs.getColumn("season_title").getUtf8(), + rs.getColumn("series_title").getUtf8() + ); + } +} +``` + +{% include [scan_query.md](../_includes/steps/08_scan_query.md) %} + +```java +private void scanQueryWithParams(long seriesID, long seasonID) { + String query + = "DECLARE $seriesId AS Uint64; " + + "DECLARE $seasonId AS Uint64; " + + "SELECT ep.title AS episode_title, sa.title AS season_title, sr.title AS series_title " + + "FROM episodes AS ep " + + "JOIN seasons AS sa ON sa.season_id = ep.season_id " + + "JOIN series AS sr ON sr.series_id = sa.series_id " + + "WHERE sa.series_id = $seriesId AND sa.season_id = $seasonId;"; + + // Type of parameter values should be exactly the same as in DECLARE statements. + Params params = Params.of( + "$seriesId", PrimitiveValue.uint64(seriesID), + "$seasonId", PrimitiveValue.uint64(seasonID) + ); + + logger.info("--[ ExecuteScanQueryWithParams ]--"); + retryCtx.supplyStatus(session -> { + ExecuteScanQuerySettings settings = ExecuteScanQuerySettings.newBuilder().build(); + return session.executeScanQuery(query, params, settings, rs -> { + while (rs.next()) { + logger.info("read episode {} of {} for {}", + rs.getColumn("episode_title").getUtf8(), + rs.getColumn("season_title").getUtf8(), + rs.getColumn("series_title").getUtf8() + ); + } + }); + }).join().expect("scan query problem"); +} +``` + +{% include [multistep_transactions.md](../_includes/steps/09_multistep_transactions.md) %} + +Для обеспечения корректности совместной работы транзакций и контекста ретраев - каждая транзация должна выполняться целиком внутри callback, передаваемого в `SessionRetryContext`. Возврат из callback должен происходить после полного завершения транзакции. + +Шаблон кода по использовании сложных транзакций в `SessionRetryContext` +```java +private void multiStepTransaction(long seriesID, long seasonID) { + retryCtx.supplyStatus(session -> { + // Multiple operations with session + ... + + // return success status to SessionRetryContext + return CompletableFuture.completedFuture(Status.SUCCESS); + }).join().expect("multistep transaction problem"); +} + +``` + +Первый шаг — подготовка и выполнение первого запроса: + +```java + String query1 + = "DECLARE $seriesId AS Uint64; " + + "DECLARE $seasonId AS Uint64; " + + "SELECT MIN(first_aired) AS from_date FROM seasons " + + "WHERE series_id = $seriesId AND season_id = $seasonId;"; + + // Execute first query to get the required values to the client. + // Transaction control settings don't set CommitTx flag to keep transaction active + // after query execution. + TxControl tx1 = TxControl.serializableRw().setCommitTx(false); + DataQueryResult res1 = session.executeDataQuery(query1, tx1, Params.of( + "$seriesId", PrimitiveValue.uint64(seriesID), + "$seasonId", PrimitiveValue.uint64(seasonID) + )).join().expect("execute data query problem"); +``` + +Затем мы можем выполнить некоторую клиентскую обработку полученных данных: + +```java + // Perform some client logic on returned values + ResultSetReader resultSet = res1.getResultSet(0); + if (!resultSet.next()) { + throw new RuntimeException("not found first_aired"); + } + LocalDate fromDate = resultSet.getColumn("from_date").getDate(); + LocalDate toDate = fromDate.plusDays(15); +``` + +И получить текущий `transaction id` для дальшейшей работы в рамках одной транзакции: + +```java + // Get active transaction id + String txId = res1.getTxId(); +``` + +Следующий шаг — создание следующего запроса, использующего результаты выполнения кода на стороне клиентского приложения: + +```java + // Construct next query based on the results of client logic + String query2 + = "DECLARE $seriesId AS Uint64;" + + "DECLARE $fromDate AS Date;" + + "DECLARE $toDate AS Date;" + + "SELECT season_id, episode_id, title, air_date FROM episodes " + + "WHERE series_id = $seriesId AND air_date >= $fromDate AND air_date <= $toDate;"; + + // Execute second query. + // Transaction control settings continues active transaction (tx) and + // commits it at the end of second query execution. + TxControl tx2 = TxControl.id(txId).setCommitTx(true); + DataQueryResult res2 = session.executeDataQuery(query2, tx2, Params.of( + "$seriesId", PrimitiveValue.uint64(seriesID), + "$fromDate", PrimitiveValue.date(fromDate), + "$toDate", PrimitiveValue.date(toDate) + )).join().expect("execute data query problem"); + + logger.info("--[ MultiStep ]--"); + ResultSetReader rs = res2.getResultSet(0); + while (rs.next()) { + logger.info("read episode {} with air date {}", + rs.getColumn("title").getUtf8(), + rs.getColumn("air_date").getDate() + ); + } +``` + +Приведенные фрагменты кода при запуске выводят на консоль текст: + +```bash +12:06:36.850 INFO App - --[ MultiStep ]-- +12:06:36.851 INFO App - read episode Grow Fast or Die Slow with air date 2018-03-25 +12:06:36.851 INFO App - read episode Reorientation with air date 2018-04-01 +12:06:36.851 INFO App - read episode Chief Operating Officer with air date 2018-04-08 +``` + +{% include [transaction_control.md](../_includes/steps/10_transaction_control.md) %} + +Фрагмент кода, демонстрирующий явное использование вызовов `beginTransaction()` и `transaction.Commit()`: + +```java +private void tclTransaction() { + retryCtx.supplyStatus(session -> { + Transaction transaction = session.beginTransaction(TransactionMode.SERIALIZABLE_READ_WRITE) + .join().expect("begin transaction problem"); + + String query + = "DECLARE $airDate AS Date; " + + "UPDATE episodes SET air_date = $airDate WHERE title = \"TBD\";"; + + Params params = Params.of("$airDate", PrimitiveValue.date(Instant.now())); + + // Execute data query. + // Transaction control settings continues active transaction (tx) + TxControl txControl = TxControl.id(transaction).setCommitTx(false); + DataQueryResult result = session.executeDataQuery(query, txControl, params) + .join().expect("execute date query problem"); + + logger.info("get transaction {}", result.getTxId()); + + // Commit active transaction (tx) + return transaction.commit(); + }).join().expect("tcl transaction problem"); +} +``` + + diff --git a/ydb/docs/ru/core/reference/ydb-sdk/example/toc_i.yaml b/ydb/docs/ru/core/reference/ydb-sdk/example/toc_i.yaml index a030cd21a2..259520ff2b 100644 --- a/ydb/docs/ru/core/reference/ydb-sdk/example/toc_i.yaml +++ b/ydb/docs/ru/core/reference/ydb-sdk/example/toc_i.yaml @@ -8,7 +8,7 @@ items: - name: Go href: go/index.md - name: Java - href: example-java.md + href: java/index.md - name: Node.js href: example-nodejs.md - name: PHP diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/session_pool_limit/_includes/java.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/session_pool_limit/_includes/java.md new file mode 100644 index 0000000000..402c5e65ba --- /dev/null +++ b/ydb/docs/ru/core/reference/ydb-sdk/recipes/session_pool_limit/_includes/java.md @@ -0,0 +1,7 @@ +```java +this.tableClient = TableClient.newClient(rpc) + // 10 - minimum number of active sessions to keep in the pool during the cleanup + // 500 - maximum number of sessions in the pool + .sessionPoolSize(10, 500) + .build(); +```
\ No newline at end of file diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/session_pool_limit/index.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/session_pool_limit/index.md index 388dca88f1..0377e9c4c1 100644 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/session_pool_limit/index.md +++ b/ydb/docs/ru/core/reference/ydb-sdk/recipes/session_pool_limit/index.md @@ -17,5 +17,9 @@ {% include [go.md](_includes/go.md) %} +- Java + + + {% include [java.md](_includes/java.md) %} {% endlist %} |