use of org.corfudb.runtime.exceptions.TransactionAbortedException in project CorfuDB by CorfuDB.
the class UndoTest method ckMultiStreamRollback.
/**
* In this test, transactions are started on two threads, 1, 2.
* Then two things happen:
*
* 1. some updates are committed
* then t1 resumes and should roll back these commits.
*
* 2. then t2 is resumed and makes optimistic updates, which should roll
* back
* @throws Exception
*/
@Test
public void ckMultiStreamRollback() throws Exception {
ArrayList<Map> maps = new ArrayList<>();
final int nmaps = 3;
for (int i = 0; i < nmaps; i++) maps.add((SMRMap<Integer, String>) instantiateCorfuObject(new TypeToken<SMRMap<Integer, String>>() {
}, "test stream" + i));
// before t1 starts
crossStream(maps, normalValue);
// t1 starts transaction.
// snapshot should include all the keys inserted above
t(t1, () -> {
WWTXBegin();
// size() is called to make the TX obtains a snapshot at this point,
maps.get(0).size();
// and does not wait to lazily obtain it later, when it reads for
// the first time
});
// t2 starts transaction.
t(t2, () -> {
WWTXBegin();
// size() is called to make the TX obtains a snapshot at this point,
maps.get(0).size();
// and does not wait to lazily obtain it later, when it reads for
// the first time
});
// t3 modifies everything
t(t3, () -> crossStream(maps, specialValue));
// t1 should undo everything by t2 and by t3
t(t1, () -> {
for (Map m : maps) {
assertThat(m.get(specialKey)).isEqualTo(normalValue);
assertThat(m.get(specialKey + 1)).isEqualTo(normalValue);
}
});
// now, t2 optimistically modifying everything, but
// not yet committing
t(t2, () -> {
for (Map m : maps) m.put(specialKey, specialValue2);
});
// main thread, t2's work should be committed
for (Map m : maps) {
assertThat(m.get(specialKey)).isEqualTo(specialValue);
assertThat(m.get(specialKey + 1)).isEqualTo(specialValue);
}
// now, try to commit t2
t(t2, () -> {
boolean aborted = false;
try {
TXEnd();
} catch (TransactionAbortedException te) {
aborted = true;
}
assertThat(aborted);
});
// back to main thread, t2's work should be committed
for (Map m : maps) {
assertThat(m.get(specialKey)).isEqualTo(specialValue);
assertThat(m.get(specialKey + 1)).isEqualTo(specialValue);
}
}
use of org.corfudb.runtime.exceptions.TransactionAbortedException in project CorfuDB by CorfuDB.
the class CorfuCompileProxy method abortTransaction.
private void abortTransaction(Exception e) {
long snapshot_timestamp;
AbortCause abortCause;
AbstractTransactionalContext context = TransactionalContext.getCurrentContext();
if (e instanceof NetworkException) {
// If a 'NetworkException' was received within a transactional context, an attempt to
// 'getSnapshotTimestamp' will also fail (as it requests it to the Sequencer). A new NetworkException
// would prevent the earliest to be propagated and encapsulated as a TransactionAbortedException.
snapshot_timestamp = -1L;
abortCause = AbortCause.NETWORK;
} else {
snapshot_timestamp = context.getSnapshotTimestamp();
abortCause = AbortCause.UNDEFINED;
}
TxResolutionInfo txInfo = new TxResolutionInfo(context.getTransactionID(), snapshot_timestamp);
TransactionAbortedException tae = new TransactionAbortedException(txInfo, null, abortCause);
context.abortTransaction(tae);
TransactionalContext.removeContext();
throw tae;
}
Aggregations