use of org.neo4j.kernel.ha.HighlyAvailableGraphDatabase in project neo4j by neo4j.
the class TransactionConstraintsIT method writeOperationOnSlaveHasToBePerformedWithinTransaction.
@Test
public void writeOperationOnSlaveHasToBePerformedWithinTransaction() throws Exception {
// GIVEN
HighlyAvailableGraphDatabase aSlave = cluster.getAnySlave();
// WHEN
try {
aSlave.createNode();
fail("Shouldn't be able to do a write operation outside a transaction");
} catch (NotInTransactionException e) {
// THEN
}
}
use of org.neo4j.kernel.ha.HighlyAvailableGraphDatabase in project neo4j by neo4j.
the class TransactionConstraintsIT method deadlockDetectionInvolvingTwoSlaves.
@Test
public void deadlockDetectionInvolvingTwoSlaves() throws Exception {
HighlyAvailableGraphDatabase slave1 = cluster.getAnySlave();
deadlockDetectionBetween(slave1, cluster.getAnySlave(slave1));
}
use of org.neo4j.kernel.ha.HighlyAvailableGraphDatabase in project neo4j by neo4j.
the class TransactionConstraintsIT method writeOperationOnMasterHasToBePerformedWithinTransaction.
@Test
public void writeOperationOnMasterHasToBePerformedWithinTransaction() throws Exception {
// GIVEN
HighlyAvailableGraphDatabase master = cluster.getMaster();
// WHEN
try {
master.createNode();
fail("Shouldn't be able to do a write operation outside a transaction");
} catch (NotInTransactionException e) {
// THEN
}
}
use of org.neo4j.kernel.ha.HighlyAvailableGraphDatabase in project neo4j by neo4j.
the class TransactionConstraintsIT method deadlockDetectionBetween.
private void deadlockDetectionBetween(HighlyAvailableGraphDatabase slave1, final HighlyAvailableGraphDatabase slave2) throws Exception {
// GIVEN
// -- two members acquiring a read lock on the same entity
final Node commonNode;
try (Transaction tx = slave1.beginTx()) {
commonNode = slave1.createNode();
tx.success();
}
OtherThreadExecutor<HighlyAvailableGraphDatabase> thread2 = new OtherThreadExecutor<>("T2", slave2);
Transaction tx1 = slave1.beginTx();
Transaction tx2 = thread2.execute(new BeginTx());
tx1.acquireReadLock(commonNode);
thread2.execute(state -> tx2.acquireReadLock(commonNode));
// -- and one of them wanting (and awaiting) to upgrade its read lock to a write lock
Future<Lock> writeLockFuture = thread2.executeDontWait(state -> {
try (Transaction ignored = tx2) {
return tx2.acquireWriteLock(commonNode);
}
});
for (int i = 0; i < 10; i++) {
thread2.waitUntilThreadState(Thread.State.TIMED_WAITING, Thread.State.WAITING);
Thread.sleep(2);
}
try (// Close transaction no matter what happens
Transaction ignored = tx1) {
// WHEN
tx1.acquireWriteLock(commonNode);
// -- Deadlock detection is non-deterministic, so either the slave or the master will detect it
writeLockFuture.get();
fail("Deadlock exception should have been thrown");
} catch (DeadlockDetectedException e) {
// THEN -- deadlock should be avoided with this exception
} catch (ExecutionException e) {
// OR -- the tx2 thread fails with executionexception, caused by deadlock on its end
assertThat(e.getCause(), instanceOf(DeadlockDetectedException.class));
}
thread2.close();
}
use of org.neo4j.kernel.ha.HighlyAvailableGraphDatabase in project neo4j by neo4j.
the class TransactionConstraintsIT method startTxAsSlaveAndFinishItAfterHavingSwitchedToMasterShouldNotSucceed.
@Test
public void startTxAsSlaveAndFinishItAfterHavingSwitchedToMasterShouldNotSucceed() throws Exception {
// GIVEN
GraphDatabaseService db = cluster.getAnySlave(getSlaveOnlySlave());
// WHEN
Transaction tx = db.beginTx();
try {
db.createNode().setProperty("name", "slave");
tx.success();
} finally {
HighlyAvailableGraphDatabase oldMaster = cluster.getMaster();
cluster.shutdown(oldMaster);
// Wait for new master
cluster.await(masterAvailable(oldMaster));
assertFinishGetsTransactionFailure(tx);
}
// THEN
assertEquals(db, cluster.getMaster());
// to prevent a deadlock scenario which occurs if this test exists (and @After starts)
// before the db has recovered from its KERNEL_PANIC
awaitFullyOperational(db);
}
Aggregations