Skip to content

Commit 19aac3d

Browse files
committed
Skip commit-state for read-only transactions
1 parent 30057d8 commit 19aac3d

File tree

10 files changed

+369
-63
lines changed

10 files changed

+369
-63
lines changed

core/src/main/java/com/scalar/db/transaction/consensuscommit/CommitHandler.java

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -106,42 +106,52 @@ private void waitBeforePreparationSnapshotHookFuture(
106106
}
107107
}
108108

109-
public void commit(Snapshot snapshot) throws CommitException, UnknownTransactionStatusException {
109+
public void commit(Snapshot snapshot, boolean readOnly)
110+
throws CommitException, UnknownTransactionStatusException {
111+
boolean hasNoWritesAndDeletesInSnapshot = readOnly || snapshot.hasNoWritesAndDeletes();
112+
110113
Optional<Future<Void>> snapshotHookFuture = invokeBeforePreparationSnapshotHook(snapshot);
111-
try {
112-
prepare(snapshot);
113-
} catch (PreparationException e) {
114-
safelyCallOnFailureBeforeCommit(snapshot);
115-
abortState(snapshot.getId());
116-
rollbackRecords(snapshot);
117-
if (e instanceof PreparationConflictException) {
118-
throw new CommitConflictException(e.getMessage(), e, e.getTransactionId().orElse(null));
114+
115+
if (!hasNoWritesAndDeletesInSnapshot) {
116+
try {
117+
prepare(snapshot);
118+
} catch (PreparationException e) {
119+
safelyCallOnFailureBeforeCommit(snapshot);
120+
abortState(snapshot.getId());
121+
rollbackRecords(snapshot);
122+
if (e instanceof PreparationConflictException) {
123+
throw new CommitConflictException(e.getMessage(), e, e.getTransactionId().orElse(null));
124+
}
125+
throw new CommitException(e.getMessage(), e, e.getTransactionId().orElse(null));
126+
} catch (Exception e) {
127+
safelyCallOnFailureBeforeCommit(snapshot);
128+
throw e;
119129
}
120-
throw new CommitException(e.getMessage(), e, e.getTransactionId().orElse(null));
121-
} catch (Exception e) {
122-
safelyCallOnFailureBeforeCommit(snapshot);
123-
throw e;
124130
}
125131

126-
try {
127-
validate(snapshot);
128-
} catch (ValidationException e) {
129-
safelyCallOnFailureBeforeCommit(snapshot);
130-
abortState(snapshot.getId());
131-
rollbackRecords(snapshot);
132-
if (e instanceof ValidationConflictException) {
133-
throw new CommitConflictException(e.getMessage(), e, e.getTransactionId().orElse(null));
132+
if (!snapshot.hasNoReads()) {
133+
try {
134+
validate(snapshot);
135+
} catch (ValidationException e) {
136+
safelyCallOnFailureBeforeCommit(snapshot);
137+
abortState(snapshot.getId());
138+
rollbackRecords(snapshot);
139+
if (e instanceof ValidationConflictException) {
140+
throw new CommitConflictException(e.getMessage(), e, e.getTransactionId().orElse(null));
141+
}
142+
throw new CommitException(e.getMessage(), e, e.getTransactionId().orElse(null));
143+
} catch (Exception e) {
144+
safelyCallOnFailureBeforeCommit(snapshot);
145+
throw e;
134146
}
135-
throw new CommitException(e.getMessage(), e, e.getTransactionId().orElse(null));
136-
} catch (Exception e) {
137-
safelyCallOnFailureBeforeCommit(snapshot);
138-
throw e;
139147
}
140148

141149
waitBeforePreparationSnapshotHookFuture(snapshot, snapshotHookFuture.orElse(null));
142150

143-
commitState(snapshot);
144-
commitRecords(snapshot);
151+
if (!hasNoWritesAndDeletesInSnapshot) {
152+
commitState(snapshot);
153+
commitRecords(snapshot);
154+
}
145155
}
146156

147157
protected void handleCommitConflict(Snapshot snapshot, Exception cause)

core/src/main/java/com/scalar/db/transaction/consensuscommit/CommitHandlerWithGroupCommit.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.scalar.db.api.DistributedStorage;
66
import com.scalar.db.api.TransactionState;
77
import com.scalar.db.exception.transaction.CommitConflictException;
8+
import com.scalar.db.exception.transaction.CommitException;
89
import com.scalar.db.exception.transaction.UnknownTransactionStatusException;
910
import com.scalar.db.transaction.consensuscommit.Coordinator.State;
1011
import com.scalar.db.util.groupcommit.Emittable;
@@ -37,6 +38,16 @@ public CommitHandlerWithGroupCommit(
3738
this.groupCommitter = groupCommitter;
3839
}
3940

41+
@Override
42+
public void commit(Snapshot snapshot, boolean readOnly)
43+
throws CommitException, UnknownTransactionStatusException {
44+
if (!readOnly && snapshot.hasNoWritesAndDeletes()) {
45+
cancelGroupCommitIfNeeded(snapshot.getId());
46+
}
47+
48+
super.commit(snapshot, readOnly);
49+
}
50+
4051
@Override
4152
protected void onFailureBeforeCommit(Snapshot snapshot) {
4253
cancelGroupCommitIfNeeded(snapshot.getId());

core/src/main/java/com/scalar/db/transaction/consensuscommit/ConsensusCommit.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ public void commit() throws CommitException, UnknownTransactionStatusException {
269269
CoreError.CONSENSUS_COMMIT_EXECUTING_IMPLICIT_PRE_READ_FAILED.buildMessage(), e, getId());
270270
}
271271

272-
commit.commit(crud.getSnapshot());
272+
commit.commit(crud.getSnapshot(), crud.isReadOnly());
273273
}
274274

275275
@Override
@@ -280,7 +280,7 @@ public void rollback() {
280280
logger.warn("Failed to close the scanner", e);
281281
}
282282

283-
if (groupCommitter != null) {
283+
if (groupCommitter != null && !crud.isReadOnly()) {
284284
groupCommitter.remove(crud.getSnapshot().getId());
285285
}
286286
}

core/src/main/java/com/scalar/db/transaction/consensuscommit/ConsensusCommitManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ DistributedTransaction beginReadOnly(Isolation isolation) {
221221
DistributedTransaction begin(String txId, Isolation isolation, boolean readOnly) {
222222
checkArgument(!Strings.isNullOrEmpty(txId));
223223
checkNotNull(isolation);
224-
if (isGroupCommitEnabled()) {
224+
if (!readOnly && isGroupCommitEnabled()) {
225225
assert groupCommitter != null;
226226
txId = groupCommitter.reserve(txId);
227227
}

core/src/main/java/com/scalar/db/transaction/consensuscommit/CrudHandler.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,10 @@ public Snapshot getSnapshot() {
420420
return snapshot;
421421
}
422422

423+
public boolean isReadOnly() {
424+
return readOnly;
425+
}
426+
423427
private interface ConsensusCommitScanner extends TransactionCrudOperable.Scanner {
424428
boolean isClosed();
425429
}

core/src/main/java/com/scalar/db/transaction/consensuscommit/Snapshot.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,14 @@ public boolean containsKeyInGetSet(Get get) {
217217
return getSet.containsKey(get);
218218
}
219219

220+
public boolean hasNoWritesAndDeletes() {
221+
return writeSet.isEmpty() && deleteSet.isEmpty();
222+
}
223+
224+
public boolean hasNoReads() {
225+
return getSet.isEmpty() && scanSet.isEmpty() && scannerSet.isEmpty();
226+
}
227+
220228
public Optional<TransactionResult> getResult(Key key) throws CrudException {
221229
Optional<TransactionResult> result = readSet.getOrDefault(key, Optional.empty());
222230
return mergeResult(key, result);

0 commit comments

Comments
 (0)