Skip to content

Commit a298294

Browse files
committed
noticket: Rename IsolationLevel.SNAPSHOT to SNAPSHOT_READ_ONLY, to have more consistent naming and prepare for SNAPSHOT_READ_WRITE support
1 parent 58fbc22 commit a298294

File tree

6 files changed

+53
-27
lines changed

6 files changed

+53
-27
lines changed

aspect/src/main/java/tech/ydb/yoj/aspect/tx/YojTransactional.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
* <li>{@code ONLINE_CONSISTENT_READ_ONLY}</li>
4040
* <li>{@code ONLINE_INCONSISTENT_READ_ONLY}</li>
4141
* <li>{@code STALE_CONSISTENT_READ_ONLY}</li>
42-
* <li>{@code SNAPSHOT}</li>
42+
* <li>{@code SNAPSHOT_READ_ONLY}</li>
4343
* </ul>
4444
* If transaction is not marked as {@link #readOnly() read-only}, isolation level is ignored.
4545
*/

repository-ydb-v2/src/main/java/tech/ydb/yoj/repository/ydb/YdbRepositoryTransaction.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
import tech.ydb.yoj.ExperimentalApi;
4141
import tech.ydb.yoj.repository.BaseDb;
4242
import tech.ydb.yoj.repository.db.Entity;
43-
import tech.ydb.yoj.repository.db.IsolationLevel;
4443
import tech.ydb.yoj.repository.db.QueryStatsMode;
4544
import tech.ydb.yoj.repository.db.QueryTracingFilter;
4645
import tech.ydb.yoj.repository.db.QueryType;
@@ -221,7 +220,7 @@ private boolean isFinalActionNeeded(String actionName) {
221220
transactionLocal.log().info("No-op %s: scan tx", actionName);
222221
return false;
223222
}
224-
if (options.isReadOnly() && options.getIsolationLevel() != IsolationLevel.SNAPSHOT) {
223+
if (options.isReadOnly() && !options.getIsolationLevel().isSnapshot()) {
225224
transactionLocal.log().info("No-op %s: read-only tx @%s", actionName, options.getIsolationLevel());
226225
return false;
227226
}
@@ -263,16 +262,14 @@ private TxControl<?> getTxControl() {
263262
case ONLINE_CONSISTENT_READ_ONLY -> TxControl.onlineRo().setAllowInconsistentReads(false);
264263
case ONLINE_INCONSISTENT_READ_ONLY -> TxControl.onlineRo().setAllowInconsistentReads(true);
265264
case STALE_CONSISTENT_READ_ONLY -> TxControl.staleRo();
266-
case SNAPSHOT -> {
265+
case SNAPSHOT_READ_ONLY, SNAPSHOT -> {
267266
TxControl<?> txControl = (txId != null ? TxControl.id(txId) : TxControl.snapshotRo());
268267
yield txControl.setCommitTx(false);
269268
}
270269
};
271270
}
272271

273272
private String getYql(Statement<?, ?> statement) {
274-
// TODO(nvamelichev): Make the use of syntax_v1 directive configurable in YdbRepository.Settings
275-
// @see https://github.com/ydb-platform/yoj-project/issues/148
276273
return statement.getQuery(tablespace);
277274
}
278275

@@ -612,7 +609,7 @@ public TxMode getTxMode() {
612609
case ONLINE_CONSISTENT_READ_ONLY -> TxMode.ONLINE_RO;
613610
case ONLINE_INCONSISTENT_READ_ONLY -> TxMode.ONLINE_INCONSISTENT_RO;
614611
case STALE_CONSISTENT_READ_ONLY -> TxMode.STALE_RO;
615-
case SNAPSHOT -> TxMode.SNAPSHOT_RO;
612+
case SNAPSHOT_READ_ONLY, SNAPSHOT -> TxMode.SNAPSHOT_RO;
616613
// TxMode.NONE corresponds to DDL statements, and we have no DDL statements in YOJ transactions
617614
};
618615
}

repository-ydb-v2/src/test/java/tech/ydb/yoj/repository/ydb/YdbRepositoryIntegrationTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ public void snapshotTransactionLevel() {
339339
assertThat(actual2).isEqualTo(expected2);
340340

341341
db.readOnly()
342-
.withStatementIsolationLevel(IsolationLevel.SNAPSHOT)
342+
.withStatementIsolationLevel(IsolationLevel.SNAPSHOT_READ_ONLY)
343343
.run(() -> {
344344
Project actualSnapshot1 = db.projects().find(expected1.getId());
345345
assertThat(actualSnapshot1).isEqualTo(expected1);
@@ -1040,7 +1040,7 @@ public void ydbTransactionCompatibility() {
10401040
IsolationLevel.ONLINE_CONSISTENT_READ_ONLY, TxMode.ONLINE_RO,
10411041
IsolationLevel.ONLINE_INCONSISTENT_READ_ONLY, TxMode.ONLINE_INCONSISTENT_RO,
10421042
IsolationLevel.STALE_CONSISTENT_READ_ONLY, TxMode.STALE_RO,
1043-
IsolationLevel.SNAPSHOT, TxMode.SNAPSHOT_RO
1043+
IsolationLevel.SNAPSHOT_READ_ONLY, TxMode.SNAPSHOT_RO
10441044
).entrySet()) {
10451045
var isolationLevel = entry.getKey();
10461046
var txMode = entry.getValue();
@@ -1134,7 +1134,7 @@ public void queryStatsCollectionMode() {
11341134
.withQueryStats(QueryStatsMode.FULL)
11351135
.readOnly()
11361136
.noFirstLevelCache()
1137-
.withStatementIsolationLevel(IsolationLevel.SNAPSHOT)
1137+
.withStatementIsolationLevel(IsolationLevel.SNAPSHOT_READ_ONLY)
11381138
.run(() -> db.table(UniqueProject.class).query()
11391139
.where("id").in(List.of(
11401140
new UniqueProject.Id("id501"),
@@ -1194,7 +1194,7 @@ public void customQueryTracingFilter() {
11941194
.noQueryTracing()
11951195
.readOnly()
11961196
.noFirstLevelCache()
1197-
.withStatementIsolationLevel(IsolationLevel.SNAPSHOT);
1197+
.withStatementIsolationLevel(IsolationLevel.SNAPSHOT_READ_ONLY);
11981198
var found = txMgr2.run(() -> db.table(ToStringCountingProject.class).find(new ToStringCountingProject.Id("id3")));
11991199
assertThat(found).isEqualTo(project3);
12001200

repository/src/main/java/tech/ydb/yoj/repository/db/IsolationLevel.java

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,13 @@
1010
*/
1111
public enum IsolationLevel {
1212
/**
13-
* All transactions are serialized one-by-one. If the DB detects a write collision among
14-
* several concurrent transactions, only the first one is committed.
15-
* This is the strongest level. And the only level at which data changes are possible.
13+
* All transactions are serialized <em>as if</em> they are executed one-by-one. If the DB detects a write collision
14+
* among several concurrent transactions, only one of them is committed, and all others get a "Transaction locks
15+
* invalidated" (TLI) error, represented by YOJ
16+
* {@link tech.ydb.yoj.repository.db.exception.OptimisticLockException OptimisticLockException}. This causes
17+
* the transaction body to be retried by the {@link TxManager transaction manager},
18+
* unless the {@link TxManager#withMaxRetries(int) retry count} is exhausted.
19+
* <p>This is the strongest isolation level.
1620
*/
1721
SERIALIZABLE_READ_WRITE(""),
1822

@@ -23,23 +27,33 @@ public enum IsolationLevel {
2327

2428
/**
2529
* The most recent inconsistent state of the database. Read only.
26-
* A phantom read may occurs when, in the course of a transaction, some new rows are added
27-
* by another transaction to the records being read. This is the weakest level.
30+
* A phantom read may occur when, during the course of a transaction, some new rows are added
31+
* by another transaction to the records being read.
32+
* <p>This is the weakest isolation level.
2833
*/
2934
ONLINE_INCONSISTENT_READ_ONLY("OI"),
3035

3136
/**
3237
* An <em>almost</em> recent consistent state of the database. Read only.
33-
* This level is faster then {@code ONLINE_CONSISTENT_READ_ONLY}, but may return stale data.
38+
* This level is faster than {@link #ONLINE_CONSISTENT_READ_ONLY}, but may return stale data.
3439
*/
3540
STALE_CONSISTENT_READ_ONLY("SC"),
3641

3742
/**
38-
* All the read operations within a transaction access the database snapshot. Read only.
43+
* @deprecated Same as {@link #SNAPSHOT_READ_ONLY}, but unfortunately named. Please use {@link #SNAPSHOT_READ_ONLY}
44+
* instead; the {@code IsolationLevel.SNAPSHOT} constant will be removed in YOJ 2.9.0.
45+
*/
46+
@Deprecated(forRemoval = true)
47+
SNAPSHOT("SP"),
48+
49+
/**
50+
* All read operations within a transaction access the database snapshot. Read only.
3951
* All the data reads are consistent. The snapshot is taken when the transaction begins,
4052
* meaning the transaction sees all changes committed before it began.
4153
*/
42-
SNAPSHOT("SP");
54+
SNAPSHOT_READ_ONLY("SP");
55+
56+
// TODO(nvamelichev): Add support for SNAPSHOT_RW
4357

4458
@Getter
4559
private final String txIdSuffix;
@@ -68,4 +82,16 @@ public boolean isReadOnly() {
6882
public boolean isReadWrite() {
6983
return this == SERIALIZABLE_READ_WRITE;
7084
}
85+
86+
/**
87+
* Indicates whether the transaction offers <em>snapshot isolation</em>; YDB offers both read-only and read-write
88+
* snapshot isolation.
89+
*
90+
* @return {@code true} if the transaction offers snapshot isolation; {@code false} otherwise
91+
* @see #isReadOnly()
92+
* @see #isReadWrite()
93+
*/
94+
public boolean isSnapshot() {
95+
return this == SNAPSHOT_READ_ONLY || this == SNAPSHOT;
96+
}
7197
}

repository/src/main/java/tech/ydb/yoj/repository/db/TxManager.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,7 @@ default TxManager noQueryTracing() {
196196

197197
/**
198198
* Performs the specified action inside a transaction. The action must be idempotent, because it might be executed
199-
* multiple times in case of {@link OptimisticLockException transaction lock
200-
* invalidation}.
199+
* multiple times in case of {@link OptimisticLockException transaction lock invalidation}.
201200
*
202201
* @param supplier action to perform
203202
* @return action result
@@ -206,8 +205,7 @@ default TxManager noQueryTracing() {
206205

207206
/**
208207
* Performs the specified action inside a transaction. The action must be idempotent, because it might be executed
209-
* multiple times in case of {@link OptimisticLockException transaction lock
210-
* invalidation}.
208+
* multiple times in case of {@link OptimisticLockException transaction lock invalidation}.
211209
*
212210
* @param runnable action to perform
213211
*/
@@ -216,11 +214,12 @@ default TxManager noQueryTracing() {
216214
/**
217215
* Start a transaction-like session of read-only statements. Each statement will be executed <em>separately</em>,
218216
* with the specified isolation level (online consistent read-only, by default).
219-
* <p>YDB doesn't currently support multi-statement read-only transactions. If you perform more than one read, be
220-
* ready to handle potential inconsistencies between the reads.
217+
* <p>YDB currently supports multi-statement read-only transactions only on {@link IsolationLevel#SNAPSHOT_READ_ONLY
218+
* snapshot read-only isolation level}. If you perform more than one read statement on any other read-only isolation
219+
* level, you must be ready to handle potential inconsistencies between the reads.
221220
* <p>You can also use {@code readOnly().run(() -> [table].readTable(...));} to efficiently read data from the table
222221
* without interfering with OLTP transactions. In this case, data consistency is similar to snapshot isolation. If
223-
* perform more than one {@code readTable()}, be ready to handle potential inconsistencies between the reads.
222+
* perform more than one {@code readTable()}, you must be ready to handle potential inconsistencies between the reads.
224223
*/
225224
ReadonlyBuilder readOnly();
226225

repository/src/main/java/tech/ydb/yoj/repository/db/TxOptions.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ public boolean isScan() {
7676
return scanOptions != null;
7777
}
7878

79+
public boolean isSnapshot() {
80+
return isolationLevel.isSnapshot();
81+
}
82+
7983
public TimeoutOptions minTimeoutOptions(Duration timeoutFromExternalCtx) {
8084
if (timeoutFromExternalCtx == null && timeoutOptions == null) {
8185
return TimeoutOptions.DEFAULT;
@@ -109,7 +113,7 @@ public static class TimeoutOptions {
109113
Duration timeout;
110114

111115
/**
112-
* Calculates <b>canceAfter</b> parameter for ydb sdk, which must be 50-100ms less than a transport timeout.
116+
* Calculates <b>canceAfter</b> parameter for YDB SDK, which must be 50-100ms less than a transport timeout.
113117
* The bigger the transport timeout, the bigger the difference.
114118
*/
115119
public Duration getCancelAfter() {

0 commit comments

Comments
 (0)