use of org.apache.ignite.internal.tx.InternalTransaction in project ignite-3 by apache.
the class TxAbstractTest method testIncrement2.
/**
* Tests if a lost update is not happening on concurrent increment.
*/
@Test
public void testIncrement2() throws TransactionException, InterruptedException {
InternalTransaction tx = (InternalTransaction) igniteTransactions.begin();
InternalTransaction tx2 = (InternalTransaction) igniteTransactions.begin();
Tuple key = makeKey(1);
Tuple val = makeValue(1, 100.);
// Creates implicit transaction.
accounts.recordView().upsert(null, val);
var table = accounts.recordView();
var table2 = accounts.recordView();
// Read in tx
double valTx = table.get(tx, key).doubleValue("balance");
// Read in tx2
double valTx2 = table2.get(tx2, key).doubleValue("balance");
// Write in tx2 (should wait for read unlock in tx1)
CompletableFuture<Void> fut = table2.upsertAsync(tx2, makeValue(1, valTx2 + 1));
// Give some time to update lock queue TODO asch IGNITE-15928
Thread.sleep(300);
assertFalse(fut.isDone());
CompletableFuture<Void> fut2 = fut.thenCompose(ret -> tx2.commitAsync());
// Write in tx
table.upsert(tx, makeValue(1, valTx + 1));
tx.commit();
Exception err = assertThrows(Exception.class, () -> fut2.get(5, TimeUnit.SECONDS));
assertTrue(err.getMessage().contains("Failed to acquire a lock"), err.getMessage());
assertEquals(101., accounts.recordView().get(null, key).doubleValue("balance"));
}
use of org.apache.ignite.internal.tx.InternalTransaction in project ignite-3 by apache.
the class TxAbstractTest method doTestSingleKeyMultithreaded.
/**
* Performs a test.
*
* @param duration The duration.
* @param verbose Verbose mode.
* @throws InterruptedException If interrupted while waiting.
*/
private void doTestSingleKeyMultithreaded(long duration, boolean verbose) throws InterruptedException {
int threadsCnt = Runtime.getRuntime().availableProcessors() * 2;
Thread[] threads = new Thread[threadsCnt];
final double initial = 1000;
final double total = threads.length * initial;
for (int i = 0; i < threads.length; i++) {
accounts.recordView().upsert(null, makeValue(i, 1000));
}
double total0 = 0;
for (long i = 0; i < threads.length; i++) {
double balance = accounts.recordView().get(null, makeKey(i)).doubleValue("balance");
total0 += balance;
}
assertEquals(total, total0, "Total amount invariant is not preserved");
CyclicBarrier startBar = new CyclicBarrier(threads.length, () -> log.info("Before test"));
LongAdder ops = new LongAdder();
LongAdder fails = new LongAdder();
AtomicBoolean stop = new AtomicBoolean();
Random r = new Random();
AtomicReference<Throwable> firstErr = new AtomicReference<>();
for (int i = 0; i < threads.length; i++) {
long finalI = i;
threads[i] = new Thread(new Runnable() {
@Override
public void run() {
try {
startBar.await();
} catch (Exception e) {
fail();
}
while (!stop.get() && firstErr.get() == null) {
InternalTransaction tx = txManager(accounts).begin();
var table = accounts.recordView();
try {
long acc1 = finalI;
double amount = 100 + r.nextInt(500);
if (verbose) {
log.info("op=tryGet ts={} id={}", tx.timestamp(), acc1);
}
double val0 = table.get(tx, makeKey(acc1)).doubleValue("balance");
long acc2 = acc1;
while (acc1 == acc2) {
acc2 = r.nextInt(threads.length);
}
if (verbose) {
log.info("op=tryGet ts={} id={}", tx.timestamp(), acc2);
}
double val1 = table.get(tx, makeKey(acc2)).doubleValue("balance");
if (verbose) {
log.info("op=tryPut ts={} id={}", tx.timestamp(), acc1);
}
table.upsert(tx, makeValue(acc1, val0 - amount));
if (verbose) {
log.info("op=tryPut ts={} id={}", tx.timestamp(), acc2);
}
table.upsert(tx, makeValue(acc2, val1 + amount));
tx.commit();
assertTrue(txManager(accounts).state(tx.timestamp()) == COMMITED);
ops.increment();
} catch (Exception e) {
assertTrue(e.getMessage().contains("Failed to acquire a lock"), e.getMessage());
fails.increment();
}
}
}
});
threads[i].setName("Worker-" + i);
threads[i].setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
firstErr.compareAndExchange(null, e);
}
});
threads[i].start();
}
Thread.sleep(duration);
stop.set(true);
for (Thread thread : threads) {
thread.join(3_000);
}
if (firstErr.get() != null) {
throw new IgniteException(firstErr.get());
}
log.info("After test ops={} fails={}", ops.sum(), fails.sum());
total0 = 0;
for (long i = 0; i < threads.length; i++) {
double balance = accounts.recordView().get(null, makeKey(i)).doubleValue("balance");
total0 += balance;
}
assertEquals(total, total0, "Total amount invariant is not preserved");
}
use of org.apache.ignite.internal.tx.InternalTransaction in project ignite-3 by apache.
the class TxAbstractTest method testAbortNoUpdate.
@Test
public void testAbortNoUpdate() throws TransactionException {
accounts.recordView().upsert(null, makeValue(1, 100.));
InternalTransaction tx = (InternalTransaction) igniteTransactions.begin();
tx.rollback();
assertEquals(100., accounts.recordView().get(null, makeKey(1)).doubleValue("balance"));
}
use of org.apache.ignite.internal.tx.InternalTransaction in project ignite-3 by apache.
the class TxAbstractTest method testReorder.
@Test
public void testReorder() throws Exception {
accounts.recordView().upsert(null, makeValue(1, 100.));
InternalTransaction tx = (InternalTransaction) igniteTransactions.begin();
InternalTransaction tx2 = (InternalTransaction) igniteTransactions.begin();
InternalTransaction tx3 = (InternalTransaction) igniteTransactions.begin();
var table = accounts.recordView();
var table2 = accounts.recordView();
var table3 = accounts.recordView();
double v0 = table.get(tx, makeKey(1)).doubleValue("balance");
double v1 = table3.get(tx3, makeKey(1)).doubleValue("balance");
assertEquals(v0, v1);
CompletableFuture<Void> fut = table3.upsertAsync(tx3, makeValue(1, v0 + 10));
assertFalse(fut.isDone());
// Give some time to update lock queue TODO asch IGNITE-15928
Thread.sleep(300);
table.upsert(tx, makeValue(1, v0 + 20));
CompletableFuture<Tuple> fut2 = table2.getAsync(tx2, makeKey(1));
assertFalse(fut2.isDone());
tx.commit();
fut2.get();
tx2.rollback();
Exception err = assertThrows(Exception.class, () -> fut.get(5, TimeUnit.SECONDS));
assertTrue(err.getMessage().contains("Failed to acquire a lock"), err.getMessage());
}
use of org.apache.ignite.internal.tx.InternalTransaction in project ignite-3 by apache.
the class TxAbstractTest method testReorder2.
@Test
public void testReorder2() throws Exception {
accounts.recordView().upsert(null, makeValue(1, 100.));
InternalTransaction tx = (InternalTransaction) igniteTransactions.begin();
InternalTransaction tx2 = (InternalTransaction) igniteTransactions.begin();
InternalTransaction tx3 = (InternalTransaction) igniteTransactions.begin();
var table = accounts.recordView();
var table2 = accounts.recordView();
var table3 = accounts.recordView();
double v0 = table.get(tx, makeKey(1)).doubleValue("balance");
table.upsertAsync(tx, makeValue(1, v0 + 10));
CompletableFuture<Tuple> fut = table2.getAsync(tx2, makeKey(1));
assertFalse(fut.isDone());
CompletableFuture<Tuple> fut2 = table3.getAsync(tx3, makeKey(1));
assertFalse(fut2.isDone());
}
Aggregations