use of com.cadenzauk.siesta.model.LockTestRow in project siesta by cadenzauk.
the class LockingIntegrationTest method updateWithoutTimeout.
@Test
void updateWithoutTimeout() throws InterruptedException {
long id = newId();
Database database = TestDatabase.testDatabase(dataSource);
Synchronization thread1 = new Synchronization();
Synchronization thread2 = new Synchronization();
database.insert(new LockTestRow(id, 1, "Initial"));
CompletableFuture<Boolean> update1 = CompletableFuture.supplyAsync(() -> performUpdate(false, database, id, thread1));
CompletableFuture<Boolean> update2 = CompletableFuture.supplyAsync(() -> performUpdate(false, database, id, thread2));
thread1.select();
thread2.select();
thread1.update();
thread2.updateAsync();
TimeUnit.MILLISECONDS.sleep(100);
thread1.commit();
boolean update1Succeeded = update1.join();
boolean update2Succeeded = update2.join();
assertThat(update1Succeeded, is(true));
assertThat(update2Succeeded, is(false));
}
use of com.cadenzauk.siesta.model.LockTestRow in project siesta by cadenzauk.
the class LockingIntegrationTest method updateWithTimeout1.
@Test
void updateWithTimeout1() {
assumeTrue(dialect.supportsLockTimeout(), "Database does not support lock timeouts.");
long id = newId();
Database database = TestDatabase.testDatabase(dataSource);
Synchronization thread1 = new Synchronization();
Synchronization thread2 = new Synchronization();
CompletableFuture<Boolean> update1 = CompletableFuture.supplyAsync(() -> performUpdate(true, database, id, thread1));
CompletableFuture<Boolean> update2 = CompletableFuture.supplyAsync(() -> performUpdate(true, database, id, thread2));
database.insert(new LockTestRow(id, 1, "Initial"));
thread1.select();
thread1.update();
thread2.select();
thread2.update();
thread1.commit();
boolean update2Succeeded = update2.join();
boolean update1Succeeded = update1.join();
assertThat(update1Succeeded, is(true));
assertThat(update2Succeeded, is(false));
}
use of com.cadenzauk.siesta.model.LockTestRow in project siesta by cadenzauk.
the class LockingIntegrationTest method performUpdate.
private boolean performUpdate(boolean setLockTimeout, Database database, long id, Synchronization synchronization) {
try (CompositeAutoCloseable closeable = new CompositeAutoCloseable()) {
synchronization.waitToSelect();
Transaction transaction = closeable.add(database.beginTransaction());
Optional<Integer> currentRevision = database.from(LockTestRow.class).select(LockTestRow::revision).where(LockTestRow::id).isEqualTo(id).optional(transaction);
LOG.info("Current revision = {}", currentRevision);
Optional<Integer> uncommittedRevision = database.from(LockTestRow.class).select(LockTestRow::revision).where(LockTestRow::id).isEqualTo(id).withIsolation(IsolationLevel.UNCOMMITTED_READ).optional(transaction);
LOG.info("Uncommitted revision = {}", uncommittedRevision);
if (uncommittedRevision.orElse(0) > currentRevision.orElse(0)) {
LOG.info("Updated by another transaction - could bail at this point", currentRevision, uncommittedRevision);
}
synchronization.waitToUpdate();
if (setLockTimeout) {
closeable.add(database.withLockTimeout(transaction, 0, TimeUnit.SECONDS));
}
int updateCount = currentRevision.map(curr -> database.update(LockTestRow.class).set(LockTestRow::updatedBy).to(Thread.currentThread().getName()).set(LockTestRow::revision).to(curr + 1).where(LockTestRow::id).isEqualTo(id).and(LockTestRow::revision).isEqualTo(curr).execute(transaction)).orElseGet(() -> database.insert(transaction, new LockTestRow(id, 1, Thread.currentThread().getName())));
LOG.info("Update count = {}", updateCount);
if (updateCount == 0) {
synchronization.finished();
return false;
}
synchronization.waitToCommit();
transaction.commit();
LOG.info("Committed");
synchronization.finished();
return true;
} catch (RuntimeSqlException e) {
LOG.error("Update failed", e);
synchronization.updateFailed();
return false;
}
}
use of com.cadenzauk.siesta.model.LockTestRow in project siesta by cadenzauk.
the class LockingIntegrationTest method updateWithTimeout3.
@Test
void updateWithTimeout3() {
assumeTrue(dialect.supportsLockTimeout(), "Database does not support lock timeouts.");
Database database = TestDatabase.testDatabase(dataSource);
long id = newId();
Synchronization thread1 = new Synchronization();
Synchronization thread2 = new Synchronization();
CompletableFuture<Boolean> update1 = CompletableFuture.supplyAsync(() -> performUpdate(true, database, id, thread1));
CompletableFuture<Boolean> update2 = CompletableFuture.supplyAsync(() -> performUpdate(true, database, id, thread2));
database.insert(new LockTestRow(id, 1, "Initial"));
thread1.select();
thread1.update();
thread2.select();
thread1.commit();
thread2.update();
boolean update2Succeeded = update2.join();
boolean update1Succeeded = update1.join();
assertThat(update1Succeeded, is(true));
assertThat(update2Succeeded, is(false));
}
use of com.cadenzauk.siesta.model.LockTestRow in project siesta by cadenzauk.
the class LockingIntegrationTest method updateWithTimeout2.
@Test
void updateWithTimeout2() {
assumeTrue(dialect.supportsLockTimeout(), "Database does not support lock timeouts.");
Database database = TestDatabase.testDatabase(dataSource);
long id = newId();
Synchronization thread1 = new Synchronization();
Synchronization thread2 = new Synchronization();
CompletableFuture<Boolean> update1 = CompletableFuture.supplyAsync(() -> performUpdate(true, database, id, thread1));
CompletableFuture<Boolean> update2 = CompletableFuture.supplyAsync(() -> performUpdate(true, database, id, thread2));
database.insert(new LockTestRow(id, 1, "Initial"));
thread1.select();
thread2.select();
thread1.update();
thread2.update();
thread1.commit();
boolean update2Succeeded = update2.join();
boolean update1Succeeded = update1.join();
assertThat(update1Succeeded, is(true));
assertThat(update2Succeeded, is(false));
}
Aggregations