package org.multiverse.stms.gamma.integration.isolation;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.multiverse.api.exceptions.ReadWriteConflict;
import org.multiverse.stms.gamma.GammaConstants;
import org.multiverse.stms.gamma.GammaStm;
import org.multiverse.stms.gamma.transactionalobjects.GammaTxnLong;
import org.multiverse.stms.gamma.transactionalobjects.Tranlocal;
import org.multiverse.stms.gamma.transactions.GammaTxn;
import static org.junit.Assert.fail;
import static org.multiverse.TestUtils.assertIsAborted;
import static org.multiverse.TestUtils.assertIsCommitted;
import static org.multiverse.api.GlobalStmInstance.getGlobalStmInstance;
import static org.multiverse.api.TxnThreadLocal.clearThreadLocalTxn;
import static org.multiverse.stms.gamma.GammaTestUtils.assertVersionAndValue;
public class WriteConflictTest implements GammaConstants {
private GammaStm stm;
@Before
public void setUp() {
clearThreadLocalTxn();
stm = (GammaStm) getGlobalStmInstance();
}
@After
public void tearDown() {
clearThreadLocalTxn();
}
@Test
public void whenDirtyCheckAndChange_ThenWriteConflict() {
GammaTxnLong ref = new GammaTxnLong(stm);
GammaTxn tx = stm.newTxnFactoryBuilder()
.setSpeculative(false)
.setDirtyCheckEnabled(true)
.newTransactionFactory()
.newTxn();
Tranlocal write = ref.openForWrite(tx, LOCKMODE_NONE);
write.long_value++;
ref.atomicIncrementAndGet(1);
long version = ref.getVersion();
try {
tx.commit();
fail();
} catch (ReadWriteConflict expected) {
}
assertIsAborted(tx);
assertVersionAndValue(ref, version, 1);
}
@Test
public void whenDirtyCheckAndNoChange_ThenNoWriteConflict() {
GammaTxnLong ref = new GammaTxnLong(stm);
GammaTxn tx = stm.newTxnFactoryBuilder()
.setSpeculative(false)
.setDirtyCheckEnabled(true)
.newTransactionFactory()
.newTxn();
ref.openForWrite(tx, LOCKMODE_NONE);
ref.atomicIncrementAndGet(1);
long version = ref.getVersion();
tx.commit();
assertIsCommitted(tx);
assertVersionAndValue(ref, version, 1);
}
@Test
public void whenNoDirtyCheckAndChange_ThenWriteConflict() {
GammaTxnLong ref = new GammaTxnLong(stm);
GammaTxn tx = stm.newTxnFactoryBuilder()
.setSpeculative(false)
.setDirtyCheckEnabled(false)
.newTransactionFactory()
.newTxn();
Tranlocal write = ref.openForWrite(tx, LOCKMODE_NONE);
write.long_value++;
ref.atomicIncrementAndGet(1);
long version = ref.getVersion();
try {
tx.commit();
fail();
} catch (ReadWriteConflict expected) {
}
assertIsAborted(tx);
assertVersionAndValue(ref, version, 1);
}
@Test
public void whenNoDirtyCheckAndNoChange_ThenWriteConflict() {
GammaTxnLong ref = new GammaTxnLong(stm);
GammaTxn tx = stm.newTxnFactoryBuilder()
.setSpeculative(false)
.setDirtyCheckEnabled(false)
.newTransactionFactory()
.newTxn();
Tranlocal write = ref.openForWrite(tx, LOCKMODE_NONE);
write.long_value++;
ref.atomicIncrementAndGet(1);
long version = ref.getVersion();
try {
tx.commit();
fail();
} catch (ReadWriteConflict expected) {
}
assertIsAborted(tx);
assertVersionAndValue(ref, version, 1);
}
}