Skip to content

Commit 798ffb4

Browse files
committed
Added SnapshotRO mode to YdbTxState
1 parent bdcf39a commit 798ffb4

File tree

1 file changed

+77
-84
lines changed

1 file changed

+77
-84
lines changed

jdbc/src/main/java/tech/ydb/jdbc/context/YdbTxState.java

Lines changed: 77 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -13,68 +13,90 @@
1313
* @author Aleksandr Gorshenin
1414
*/
1515
public class YdbTxState {
16+
private final int transactionLevel;
17+
private final boolean isReadOnly;
18+
private final boolean isAutoCommit;
19+
1620
private final TxControl<?> txControl;
17-
protected final int transactionLevel;
1821

19-
protected YdbTxState(TxControl<?> tx, int level) {
20-
this.txControl = tx;
22+
protected YdbTxState(TxControl<?> txControl, int level, boolean isReadOnly, boolean isAutoCommit) {
2123
this.transactionLevel = level;
24+
this.isReadOnly = isReadOnly;
25+
this.isAutoCommit = isAutoCommit;
26+
this.txControl = txControl;
27+
}
28+
29+
protected YdbTxState(TxControl<?> txControl, YdbTxState other) {
30+
this.transactionLevel = other.transactionLevel;
31+
this.isReadOnly = other.isReadOnly;
32+
this.isAutoCommit = other.isAutoCommit;
33+
this.txControl = txControl;
2234
}
2335

2436
@Override
2537
public String toString() {
26-
return "NoTx" + transactionLevel;
38+
return "NoTx";
2739
}
2840

2941
public String txID() {
3042
return null;
3143
}
3244

45+
public boolean isInsideTransaction() {
46+
return false;
47+
}
48+
3349
public TxControl<?> txControl() {
3450
return txControl;
3551
}
3652

3753
public boolean isAutoCommit() {
38-
return txControl.isCommitTx();
54+
return isAutoCommit;
3955
}
4056

4157
public boolean isReadOnly() {
42-
return transactionLevel != Connection.TRANSACTION_SERIALIZABLE;
58+
return isReadOnly;
4359
}
4460

45-
public boolean isInsideTransaction() {
46-
return false;
47-
}
48-
49-
public int transactionLevel() throws SQLException {
61+
public int transactionLevel() {
5062
return transactionLevel;
5163
}
5264

5365
public YdbTxState withAutoCommit(boolean newAutoCommit) throws SQLException {
54-
if (newAutoCommit == isAutoCommit()) {
66+
if (newAutoCommit == isAutoCommit) {
5567
return this;
5668
}
57-
return create(transactionLevel(), newAutoCommit);
69+
70+
if (isInsideTransaction()) {
71+
throw new SQLFeatureNotSupportedException(YdbConst.CHANGE_ISOLATION_INSIDE_TX);
72+
}
73+
74+
return emptyTx(transactionLevel, isReadOnly, newAutoCommit);
5875
}
5976

60-
public YdbTxState withReadOnly(boolean readOnly) throws SQLException {
61-
if (readOnly == isReadOnly()) {
77+
public YdbTxState withReadOnly(boolean newReadOnly) throws SQLException {
78+
if (newReadOnly == isReadOnly()) {
6279
return this;
6380
}
6481

65-
if (readOnly) {
66-
return create(YdbConst.ONLINE_CONSISTENT_READ_ONLY, isAutoCommit());
67-
} else {
68-
return create(Connection.TRANSACTION_SERIALIZABLE, isAutoCommit());
82+
if (isInsideTransaction()) {
83+
throw new SQLFeatureNotSupportedException(YdbConst.READONLY_INSIDE_TRANSACTION);
6984
}
85+
86+
return emptyTx(transactionLevel, newReadOnly, isAutoCommit);
7087
}
7188

7289
public YdbTxState withTransactionLevel(int newTransactionLevel) throws SQLException {
73-
if (newTransactionLevel == transactionLevel()) {
90+
if (newTransactionLevel == transactionLevel) {
7491
return this;
7592
}
7693

77-
return create(newTransactionLevel, isAutoCommit());
94+
if (isInsideTransaction()) {
95+
throw new SQLFeatureNotSupportedException(YdbConst.CHANGE_ISOLATION_INSIDE_TX);
96+
}
97+
98+
boolean newReadOnly = isReadOnly || newTransactionLevel != Connection.TRANSACTION_SERIALIZABLE;
99+
return emptyTx(newTransactionLevel, newReadOnly, isAutoCommit);
78100
}
79101

80102
public YdbTxState withCommit(Session session) {
@@ -94,7 +116,7 @@ public YdbTxState withKeepAlive(Session session) {
94116

95117
public YdbTxState withDataQuery(Session session, String txID) {
96118
if (txID != null && !txID.isEmpty()) {
97-
return new TransactionInProgress(txID, session, isAutoCommit());
119+
return new TransactionInProgress(txID, session, this);
98120
}
99121

100122
session.close();
@@ -105,88 +127,59 @@ public Session getSession(YdbContext ctx, YdbExecutor executor) throws SQLExcept
105127
return executor.createSession(ctx);
106128
}
107129

108-
public static YdbTxState create(int level, boolean autoCommit) throws SQLException {
109-
return create(null, null, level, autoCommit);
110-
}
130+
private static TxControl<?> txControl(int level, boolean isReadOnly, boolean isAutoCommit) throws SQLException {
131+
if (!isReadOnly) {
132+
// YDB support only one RW mode
133+
if (level != Connection.TRANSACTION_SERIALIZABLE) {
134+
throw new SQLException(YdbConst.UNSUPPORTED_TRANSACTION_LEVEL + level);
135+
}
136+
137+
return TxControl.serializableRw().setCommitTx(isAutoCommit);
138+
}
111139

112-
private static YdbTxState create(Session session, String txId, int level, boolean autoCommit)
113-
throws SQLException {
114140
switch (level) {
115141
case Connection.TRANSACTION_SERIALIZABLE:
116-
if (txId != null) {
117-
return new TransactionInProgress(txId, session, autoCommit);
118-
} else {
119-
if (autoCommit) {
120-
return new YdbTxState(TxControl.serializableRw(), level);
121-
} else {
122-
return new EmptyTransaction();
123-
}
124-
}
142+
return TxControl.snapshotRo().setCommitTx(isAutoCommit);
125143
case YdbConst.ONLINE_CONSISTENT_READ_ONLY:
126-
return new YdbTxState(TxControl.onlineRo(), level);
127-
case YdbConst.STALE_CONSISTENT_READ_ONLY:
128-
return new YdbTxState(TxControl.staleRo(), level);
144+
return TxControl.onlineRo().setAllowInconsistentReads(false).setCommitTx(isAutoCommit);
129145
case YdbConst.ONLINE_INCONSISTENT_READ_ONLY:
130-
return new YdbTxState(TxControl.onlineRo().setAllowInconsistentReads(true), level);
146+
return TxControl.onlineRo().setAllowInconsistentReads(true).setCommitTx(isAutoCommit);
147+
case YdbConst.STALE_CONSISTENT_READ_ONLY:
148+
return TxControl.staleRo().setCommitTx(isAutoCommit);
131149
default:
132150
throw new SQLException(YdbConst.UNSUPPORTED_TRANSACTION_LEVEL + level);
133151
}
134152
}
135153

136-
private static class EmptyTransaction extends YdbTxState {
137-
EmptyTransaction() {
138-
super(TxControl.serializableRw().setCommitTx(false), Connection.TRANSACTION_SERIALIZABLE);
139-
}
140-
141-
@Override
142-
public String toString() {
143-
return "EmptyTx" + transactionLevel;
144-
}
145-
146-
@Override
147-
public YdbTxState withDataQuery(Session session, String txID) {
148-
if (txID != null && !txID.isEmpty()) {
149-
return new TransactionInProgress(txID, session, isAutoCommit());
150-
}
154+
private static YdbTxState emptyTx(int level, boolean isReadOnly, boolean isAutoCommit) throws SQLException {
155+
TxControl<?> tx = txControl(level, isReadOnly, isAutoCommit);
156+
return new YdbTxState(tx, level, isReadOnly, isAutoCommit);
157+
}
151158

152-
session.close();
153-
return this;
154-
}
159+
public static YdbTxState create(int level, boolean isAutoCommit) throws SQLException {
160+
return emptyTx(level, level != Connection.TRANSACTION_SERIALIZABLE, isAutoCommit);
155161
}
156162

157163
private static class TransactionInProgress extends YdbTxState {
158-
private final String id;
164+
private final String txID;
159165
private final Session session;
166+
private final YdbTxState previos;
160167

161-
TransactionInProgress(String id, Session session, boolean autoCommit) {
162-
super(TxControl.id(id).setCommitTx(autoCommit), Connection.TRANSACTION_SERIALIZABLE);
163-
this.id = id;
168+
TransactionInProgress(String id, Session session, YdbTxState previosState) {
169+
super(TxControl.id(id).setCommitTx(previosState.isAutoCommit), previosState);
170+
this.txID = id;
164171
this.session = session;
172+
this.previos = previosState;
165173
}
166174

167175
@Override
168176
public String toString() {
169-
return "InTx" + transactionLevel + "[" + id + "]";
177+
return "InTx" + transactionLevel() + "[" + txID + "]";
170178
}
171179

172180
@Override
173181
public String txID() {
174-
return id;
175-
}
176-
177-
@Override
178-
public YdbTxState withAutoCommit(boolean newAutoCommit) throws SQLException {
179-
throw new SQLFeatureNotSupportedException(YdbConst.CHANGE_ISOLATION_INSIDE_TX);
180-
}
181-
182-
@Override
183-
public YdbTxState withTransactionLevel(int newTransactionLevel) throws SQLException {
184-
throw new SQLFeatureNotSupportedException(YdbConst.CHANGE_ISOLATION_INSIDE_TX);
185-
}
186-
187-
@Override
188-
public YdbTxState withReadOnly(boolean readOnly) throws SQLException {
189-
throw new SQLFeatureNotSupportedException(YdbConst.READONLY_INSIDE_TRANSACTION);
182+
return txID;
190183
}
191184

192185
@Override
@@ -202,13 +195,13 @@ public Session getSession(YdbContext ctx, YdbExecutor executor) throws SQLExcept
202195
@Override
203196
public YdbTxState withCommit(Session session) {
204197
session.close();
205-
return new EmptyTransaction();
198+
return previos;
206199
}
207200

208201
@Override
209202
public YdbTxState withRollback(Session session) {
210203
session.close();
211-
return new EmptyTransaction();
204+
return previos;
212205
}
213206

214207
@Override
@@ -223,15 +216,15 @@ public YdbTxState withDataQuery(Session session, String txID) {
223216
session.close();
224217
}
225218
this.session.close();
226-
return new EmptyTransaction();
219+
return previos;
227220
}
228221

229-
if (this.id.equals(txID)) {
222+
if (txID.equals(txID())) {
230223
if (this.session == session) {
231224
return this;
232225
}
233226
this.session.close();
234-
return new TransactionInProgress(txID, session, isAutoCommit());
227+
return new TransactionInProgress(txID, session, previos);
235228
}
236229

237230
session.close();

0 commit comments

Comments
 (0)