Search in sources :

Example 6 with InternalTransaction

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"));
}
Also used : InternalTransaction(org.apache.ignite.internal.tx.InternalTransaction) Tuple(org.apache.ignite.table.Tuple) TransactionException(org.apache.ignite.tx.TransactionException) IgniteException(org.apache.ignite.lang.IgniteException) Test(org.junit.jupiter.api.Test) IgniteAbstractTest(org.apache.ignite.internal.testframework.IgniteAbstractTest)

Example 7 with InternalTransaction

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");
}
Also used : AtomicReference(java.util.concurrent.atomic.AtomicReference) InternalTransaction(org.apache.ignite.internal.tx.InternalTransaction) TransactionException(org.apache.ignite.tx.TransactionException) IgniteException(org.apache.ignite.lang.IgniteException) CyclicBarrier(java.util.concurrent.CyclicBarrier) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) LongAdder(java.util.concurrent.atomic.LongAdder) Random(java.util.Random) IgniteException(org.apache.ignite.lang.IgniteException)

Example 8 with InternalTransaction

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"));
}
Also used : InternalTransaction(org.apache.ignite.internal.tx.InternalTransaction) Test(org.junit.jupiter.api.Test) IgniteAbstractTest(org.apache.ignite.internal.testframework.IgniteAbstractTest)

Example 9 with InternalTransaction

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());
}
Also used : InternalTransaction(org.apache.ignite.internal.tx.InternalTransaction) Tuple(org.apache.ignite.table.Tuple) TransactionException(org.apache.ignite.tx.TransactionException) IgniteException(org.apache.ignite.lang.IgniteException) Test(org.junit.jupiter.api.Test) IgniteAbstractTest(org.apache.ignite.internal.testframework.IgniteAbstractTest)

Example 10 with InternalTransaction

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());
}
Also used : InternalTransaction(org.apache.ignite.internal.tx.InternalTransaction) Tuple(org.apache.ignite.table.Tuple) Test(org.junit.jupiter.api.Test) IgniteAbstractTest(org.apache.ignite.internal.testframework.IgniteAbstractTest)

Aggregations

InternalTransaction (org.apache.ignite.internal.tx.InternalTransaction)24 IgniteAbstractTest (org.apache.ignite.internal.testframework.IgniteAbstractTest)14 Test (org.junit.jupiter.api.Test)14 Tuple (org.apache.ignite.table.Tuple)12 BinaryRow (org.apache.ignite.internal.schema.BinaryRow)8 NotNull (org.jetbrains.annotations.NotNull)8 Row (org.apache.ignite.internal.schema.row.Row)6 ArrayList (java.util.ArrayList)4 IgniteException (org.apache.ignite.lang.IgniteException)4 TransactionException (org.apache.ignite.tx.TransactionException)4 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)3 Int2ObjectMap (it.unimi.dsi.fastutil.ints.Int2ObjectMap)2 Int2ObjectOpenHashMap (it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap)2 Collection (java.util.Collection)2 Comparator (java.util.Comparator)2 List (java.util.List)2 Map (java.util.Map)2 UUID (java.util.UUID)2 CompletableFuture (java.util.concurrent.CompletableFuture)2 CompletableFuture.completedFuture (java.util.concurrent.CompletableFuture.completedFuture)2