Skip to content

Commit 7754ad3

Browse files
Merge pull request #18 from ydb-platform/fixes
2 parents 96e2ddc + badfa46 commit 7754ad3

File tree

46 files changed

+1538
-1169
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1538
-1169
lines changed

dev-1/lesson-2.1/java/src/main/java/tech/ydb/app/Application.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public static void main(String[] args) {
3333
// Создаем клиент для выполнения SQL-запросов
3434
try (QueryClient queryClient = QueryClient.newClient(grpcTransport).build()) {
3535
// Создаем контекст для автоматических повторных попыток выполнения запросов
36-
SessionRetryContext retryCtx = SessionRetryContext.create(queryClient).build();
36+
var retryCtx = SessionRetryContext.create(queryClient).build();
3737

3838
LOGGER.info("Database is available! Result `SELECT 1;` command: {}", new YdbRepository(retryCtx).SelectOne());
3939
}

dev-1/lesson-3.1/java/src/main/java/tech/ydb/app/IssueYdbRepository.java

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import java.util.concurrent.ThreadLocalRandom;
77

88
import tech.ydb.common.transaction.TxMode;
9-
import tech.ydb.query.tools.QueryReader;
109
import tech.ydb.query.tools.SessionRetryContext;
1110
import tech.ydb.table.query.Params;
1211
import tech.ydb.table.values.PrimitiveValue;
@@ -25,10 +24,10 @@ public class IssueYdbRepository {
2524
// 2. Улучшения тестируемости - можно передать mock-объект для тестов
2625
// 3. Централизованного управления конфигурацией ретраев
2726
// 4. Возможности переиспользования одного контекста для разных репозиториев
28-
private final SessionRetryContext retryCtx;
27+
private final QueryServiceHelper queryServiceHelper;
2928

3029
public IssueYdbRepository(SessionRetryContext retryCtx) {
31-
this.retryCtx = retryCtx;
30+
this.queryServiceHelper = new QueryServiceHelper(retryCtx);
3231
}
3332

3433
/**
@@ -44,23 +43,20 @@ public Issue addIssue(String title) {
4443

4544
// Выполняем UPSERT запрос для добавления тикета
4645
// Изменять данные можно только в режиме транзакции SERIALIZABLE_RW, поэтому используем его
47-
retryCtx.supplyResult(
48-
session -> session.createQuery(
49-
"""
50-
DECLARE $id AS Int64;
51-
DECLARE $title AS Text;
52-
DECLARE $created_at AS Timestamp;
53-
UPSERT INTO issues (id, title, created_at)
54-
VALUES ($id, $title, $created_at);
55-
""",
56-
TxMode.SERIALIZABLE_RW,
57-
Params.of(
58-
"$id", PrimitiveValue.newInt64(id),
59-
"$title", PrimitiveValue.newText(title),
60-
"$created_at", PrimitiveValue.newTimestamp(now)
61-
)
62-
).execute()
63-
).join().getStatus().expectSuccess("Failed upsert title");
46+
queryServiceHelper.executeQuery("""
47+
DECLARE $id AS Int64;
48+
DECLARE $title AS Text;
49+
DECLARE $created_at AS Timestamp;
50+
UPSERT INTO issues (id, title, created_at)
51+
VALUES ($id, $title, $created_at);
52+
""",
53+
TxMode.SERIALIZABLE_RW,
54+
Params.of(
55+
"$id", PrimitiveValue.newInt64(id),
56+
"$title", PrimitiveValue.newText(title),
57+
"$created_at", PrimitiveValue.newTimestamp(now)
58+
)
59+
);
6460

6561
return new Issue(id, title, now);
6662
}
@@ -76,11 +72,8 @@ public List<Issue> findAll() {
7672
// Этот режим сообщает серверу, что это транзакция только для чтения.
7773
// Это позволяет снизить накладные расходы на подготовку к изменениям и просто читать данные из
7874
// одного снимка базы данных.
79-
var resultSet = retryCtx.supplyResult(
80-
session -> QueryReader.readFrom(
81-
session.createQuery("SELECT id, title, created_at FROM issues;", TxMode.SNAPSHOT_RO)
82-
)
83-
).join().getValue();
75+
var resultSet = queryServiceHelper.executeQuery("SELECT id, title, created_at FROM issues;",
76+
TxMode.SNAPSHOT_RO, Params.empty());
8477

8578
var resultSetReader = resultSet.getResultSet(0);
8679

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package tech.ydb.app;
2+
3+
import tech.ydb.common.transaction.TxMode;
4+
import tech.ydb.query.tools.QueryReader;
5+
import tech.ydb.query.tools.SessionRetryContext;
6+
import tech.ydb.table.query.Params;
7+
8+
/**
9+
* @author Kirill Kurdyukov
10+
*/
11+
public class QueryServiceHelper {
12+
13+
// Контекст для автоматических повторных попыток выполнения запросов
14+
// Принимается извне через конструктор для:
15+
// 1. Следования принципу Dependency Injection - зависимости класса передаются ему извне
16+
// 2. Улучшения тестируемости - можно передать mock-объект для тестов
17+
// 3. Централизованного управления конфигурацией ретраев
18+
// 4. Возможности переиспользования одного контекста для разных репозиториев
19+
private final SessionRetryContext retryCtx;
20+
21+
public QueryServiceHelper(SessionRetryContext retryCtx) {
22+
this.retryCtx = retryCtx;
23+
}
24+
25+
public void executeQuery(String yql) {
26+
retryCtx.supplyResult(
27+
session -> QueryReader.readFrom(session.createQuery(yql, TxMode.NONE))
28+
).join().getValue();
29+
}
30+
31+
public QueryReader executeQuery(String yql, TxMode txMode, Params params) {
32+
return retryCtx.supplyResult(
33+
session -> QueryReader.readFrom(session.createQuery(yql, txMode, params))
34+
).join().getValue();
35+
}
36+
}
Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package tech.ydb.app;
22

3-
import tech.ydb.common.transaction.TxMode;
43
import tech.ydb.query.tools.SessionRetryContext;
54

65
/**
@@ -11,11 +10,10 @@
1110
*/
1211
public class SchemaYdbRepository {
1312

14-
// Контекст для автоматических повторных попыток выполнения запросов
15-
private final SessionRetryContext retryCtx;
13+
private final QueryServiceHelper queryServiceHelper;
1614

1715
public SchemaYdbRepository(SessionRetryContext retryCtx) {
18-
this.retryCtx = retryCtx;
16+
this.queryServiceHelper = new QueryServiceHelper(retryCtx);
1917
}
2018

2119
/**
@@ -28,27 +26,22 @@ public SchemaYdbRepository(SessionRetryContext retryCtx) {
2826
* Все поля являются обязательными.
2927
*/
3028
public void createSchema() {
31-
retryCtx.supplyResult(
32-
session -> session.createQuery(
33-
"""
34-
CREATE TABLE IF NOT EXISTS issues (
35-
id Int64 NOT NULL,
36-
title Text NOT NULL,
37-
created_at Timestamp NOT NULL,
38-
PRIMARY KEY (id)
39-
);
40-
""", TxMode.NONE
41-
).execute()
42-
).join().getStatus().expectSuccess("Can't create table issues");
29+
queryServiceHelper.executeQuery("""
30+
CREATE TABLE IF NOT EXISTS issues (
31+
id Int64 NOT NULL,
32+
title Text NOT NULL,
33+
created_at Timestamp NOT NULL,
34+
PRIMARY KEY (id)
35+
);
36+
"""
37+
);
4338
}
4439

4540
/**
4641
* Удаляет таблицу issues из базы данных
4742
* Используется для очистки схемы перед созданием новой
4843
*/
4944
public void dropSchema() {
50-
retryCtx.supplyResult(
51-
session -> session.createQuery("DROP TABLE IF EXISTS issues;", TxMode.NONE).execute()
52-
).join().getStatus().expectSuccess("Can't drop table issues");
45+
queryServiceHelper.executeQuery("DROP TABLE IF EXISTS issues;");
5346
}
5447
}

dev-1/lesson-4.1/java/src/main/java/tech/ydb/app/IssueYdbRepository.java

Lines changed: 64 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@
33
import java.time.Instant;
44
import java.util.ArrayList;
55
import java.util.List;
6-
import java.util.concurrent.CompletableFuture;
76
import java.util.concurrent.ThreadLocalRandom;
87

98
import tech.ydb.common.transaction.TxMode;
10-
import tech.ydb.core.Result;
119
import tech.ydb.query.tools.QueryReader;
1210
import tech.ydb.query.tools.SessionRetryContext;
1311
import tech.ydb.table.query.Params;
@@ -20,11 +18,11 @@
2018
* @author Kirill Kurdyukov
2119
*/
2220
public class IssueYdbRepository {
23-
// Контекст для автоматических повторных попыток выполнения запросов
24-
private final SessionRetryContext retryCtx;
21+
22+
private final QueryServiceHelper queryServiceHelper;
2523

2624
public IssueYdbRepository(SessionRetryContext retryCtx) {
27-
this.retryCtx = retryCtx;
25+
this.queryServiceHelper = new QueryServiceHelper(retryCtx);
2826
}
2927

3028
/**
@@ -33,29 +31,27 @@ public IssueYdbRepository(SessionRetryContext retryCtx) {
3331
* выполняются за один запрос к YDB.
3432
*/
3533
public List<IssueLinkCount> linkTicketsNoInteractive(long idT1, long idT2) {
36-
var valueReader = retryCtx.supplyResult(
37-
session -> QueryReader.readFrom(session.createQuery(
38-
"""
39-
DECLARE $t1 AS Int64;
40-
DECLARE $t2 AS Int64;
41-
42-
-- Обновляем счетчики связей
43-
UPDATE issues
44-
SET link_count = COALESCE(link_count, 0) + 1
45-
WHERE id IN ($t1, $t2);
46-
47-
-- Добавляем записи о связях между тикетами
48-
INSERT INTO links (source, destination)
49-
VALUES ($t1, $t2), ($t2, $t1);
50-
51-
-- Читаем обновленные данные
52-
SELECT id, link_count FROM issues
53-
WHERE id IN ($t1, $t2)
54-
""",
55-
TxMode.SERIALIZABLE_RW,
56-
Params.of("$t1", PrimitiveValue.newInt64(idT1), "$t2", PrimitiveValue.newInt64(idT2))
57-
))
58-
).join().getValue();
34+
var valueReader = queryServiceHelper.executeQuery(
35+
"""
36+
DECLARE $t1 AS Int64;
37+
DECLARE $t2 AS Int64;
38+
39+
-- Обновляем счетчики связей
40+
UPDATE issues
41+
SET link_count = COALESCE(link_count, 0) + 1
42+
WHERE id IN ($t1, $t2);
43+
44+
-- Добавляем записи о связях между тикетами
45+
INSERT INTO links (source, destination)
46+
VALUES ($t1, $t2), ($t2, $t1);
47+
48+
-- Читаем обновленные данные
49+
SELECT id, link_count FROM issues
50+
WHERE id IN ($t1, $t2)
51+
""",
52+
TxMode.SERIALIZABLE_RW,
53+
Params.of("$t1", PrimitiveValue.newInt64(idT1), "$t2", PrimitiveValue.newInt64(idT2))
54+
);
5955

6056
return getLinkTicketPairs(valueReader);
6157
}
@@ -71,13 +67,11 @@ WHERE id IN ($t1, $t2)
7167
* для определения стоит ли продолжать транзакцию и какой запрос выполнить следующим.
7268
*/
7369
public List<IssueLinkCount> linkTicketsInteractive(long idT1, long idT2) {
74-
return retryCtx.supplyResult(
75-
session -> {
76-
// Транзакция будет изменять данные, поэтому используем режим SERIALIZABLE_RW
77-
var tx = session.createNewTransaction(TxMode.SERIALIZABLE_RW);
78-
70+
return queryServiceHelper.executeInTx(
71+
TxMode.SERIALIZABLE_RW, // Транзакция будет изменять данные, поэтому используем режим SERIALIZABLE_RW
72+
tx -> {
7973
// Обновляем счетчики связей
80-
tx.createQuery("""
74+
tx.executeQuery("""
8175
DECLARE $t1 AS Int64;
8276
DECLARE $t2 AS Int64;
8377
@@ -86,36 +80,33 @@ public List<IssueLinkCount> linkTicketsInteractive(long idT1, long idT2) {
8680
WHERE id IN ($t1, $t2);
8781
""",
8882
Params.of("$t1", PrimitiveValue.newInt64(idT1), "$t2", PrimitiveValue.newInt64(idT2))
89-
).execute().join().getStatus().expectSuccess();
83+
);
9084

9185
// Добавляем записи о связях между тикетами
92-
tx.createQuery("""
86+
tx.executeQuery("""
9387
DECLARE $t1 AS Int64;
9488
DECLARE $t2 AS Int64;
9589
9690
INSERT INTO links (source, destination)
9791
VALUES ($t1, $t2), ($t2, $t1);
9892
""",
9993
Params.of("$t1", PrimitiveValue.newInt64(idT1), "$t2", PrimitiveValue.newInt64(idT2))
100-
).execute().join().getStatus().expectSuccess();
94+
);
10195

10296
// Читаем обновленные данные и фиксируем транзакцию
103-
var valueReader = QueryReader.readFrom(
104-
tx.createQueryWithCommit("""
105-
DECLARE $t1 AS Int64;
106-
DECLARE $t2 AS Int64;
107-
108-
SELECT id, link_count FROM issues
109-
WHERE id IN ($t1, $t2)
110-
""",
111-
Params.of("$t1", PrimitiveValue.newInt64(idT1), "$t2", PrimitiveValue.newInt64(idT2)))
112-
).join().getValue();
113-
114-
var linkTicketPairs = getLinkTicketPairs(valueReader);
115-
116-
return CompletableFuture.completedFuture(Result.success(linkTicketPairs));
97+
var valueReader = tx.executeQueryWithCommit("""
98+
DECLARE $t1 AS Int64;
99+
DECLARE $t2 AS Int64;
100+
101+
SELECT id, link_count FROM issues
102+
WHERE id IN ($t1, $t2)
103+
""",
104+
Params.of("$t1", PrimitiveValue.newInt64(idT1), "$t2", PrimitiveValue.newInt64(idT2))
105+
);
106+
107+
return getLinkTicketPairs(valueReader);
117108
}
118-
).join().getValue();
109+
);
119110
}
120111

121112
/**
@@ -128,25 +119,22 @@ public void addIssue(String title, String author) {
128119
var id = ThreadLocalRandom.current().nextLong();
129120
var now = Instant.now();
130121

131-
retryCtx.supplyResult(
132-
session -> session.createQuery(
133-
"""
134-
DECLARE $id AS Int64;
135-
DECLARE $title AS Text;
136-
DECLARE $created_at AS Timestamp;
137-
DECLARE $author AS Text;
138-
UPSERT INTO issues (id, title, created_at, author)
139-
VALUES ($id, $title, $created_at, $author);
140-
""",
141-
TxMode.SERIALIZABLE_RW,
142-
Params.of(
143-
"$id", PrimitiveValue.newInt64(id),
144-
"$title", PrimitiveValue.newText(title),
145-
"$created_at", PrimitiveValue.newTimestamp(now),
146-
"$author", PrimitiveValue.newText(author)
147-
)
148-
).execute()
149-
).join().getStatus().expectSuccess("Failed upsert title");
122+
queryServiceHelper.executeQuery("""
123+
DECLARE $id AS Int64;
124+
DECLARE $title AS Text;
125+
DECLARE $created_at AS Timestamp;
126+
DECLARE $author AS Text;
127+
UPSERT INTO issues (id, title, created_at, author)
128+
VALUES ($id, $title, $created_at, $author);
129+
""",
130+
TxMode.SERIALIZABLE_RW,
131+
Params.of(
132+
"$id", PrimitiveValue.newInt64(id),
133+
"$title", PrimitiveValue.newText(title),
134+
"$created_at", PrimitiveValue.newTimestamp(now),
135+
"$author", PrimitiveValue.newText(author)
136+
)
137+
);
150138
}
151139

152140
/**
@@ -156,11 +144,11 @@ UPSERT INTO issues (id, title, created_at, author)
156144
*/
157145
public List<Issue> findAll() {
158146
var titles = new ArrayList<Issue>();
159-
var resultSet = retryCtx.supplyResult(
160-
session -> QueryReader.readFrom(
161-
session.createQuery("SELECT id, title, created_at, author, COALESCE(link_count, 0) FROM issues;", TxMode.SNAPSHOT_RO)
162-
)
163-
).join().getValue();
147+
var resultSet = queryServiceHelper.executeQuery(
148+
"SELECT id, title, created_at, author, COALESCE(link_count, 0) FROM issues;",
149+
TxMode.SNAPSHOT_RO,
150+
Params.empty()
151+
);
164152

165153
var resultSetReader = resultSet.getResultSet(0);
166154

0 commit comments

Comments
 (0)