Search in sources :

Example 11 with Transaction

use of org.cojen.tupl.Transaction in project Tupl by cojen.

the class UpgradableRowUpdater method toNext.

@Override
protected LockResult toNext(Cursor c) throws IOException {
    Transaction txn = c.link();
    LockMode original = txn.lockMode();
    txn.lockMode(LockMode.UPGRADABLE_READ);
    try {
        return super.toNext(c);
    } finally {
        txn.lockMode(original);
    }
}
Also used : Transaction(org.cojen.tupl.Transaction) LockMode(org.cojen.tupl.LockMode)

Example 12 with Transaction

use of org.cojen.tupl.Transaction in project Tupl by cojen.

the class MergeCursor method link.

@Override
public Transaction link(Transaction txn) {
    Transaction old = mTxn;
    mTxn = txn;
    return old;
}
Also used : Transaction(org.cojen.tupl.Transaction)

Example 13 with Transaction

use of org.cojen.tupl.Transaction in project Tupl by cojen.

the class MergeCursor method store.

@Override
public void store(byte[] value) throws IOException {
    byte[] key = mKey;
    ViewUtils.positionCheck(key);
    Transaction txn = mTxn;
    if (txn == null) {
        txn = mView.newTransaction(null);
        try {
            store(txn, key, value);
            txn.commit();
        } finally {
            txn.reset();
        }
    } else if (txn.lockMode() != LockMode.UNSAFE) {
        txn.enter();
        try {
            store(txn, key, value);
            txn.commit();
        } finally {
            txn.exit();
        }
    } else {
        store(txn, key, value);
    }
}
Also used : Transaction(org.cojen.tupl.Transaction)

Example 14 with Transaction

use of org.cojen.tupl.Transaction in project Tupl by cojen.

the class DatabaseReplicatorTest method prepareTransfer.

private void prepareTransfer(boolean prepareCommit) throws Exception {
    // Prepared transaction should be transferred to replica and finish.
    var dbQueue = new LinkedBlockingQueue<Database>();
    var txnQueue = new LinkedBlockingQueue<Transaction>();
    Supplier<PrepareHandler> supplier = () -> new PrepareHandler() {

        private Database mDb;

        @Override
        public void init(Database db) {
            mDb = db;
        }

        @Override
        public void prepare(Transaction txn, byte[] message) throws IOException {
            dbQueue.add(mDb);
            txnQueue.add(txn);
        }

        @Override
        public void prepareCommit(Transaction txn, byte[] message) throws IOException {
            prepare(txn, message);
        }
    };
    Database[] dbs = startGroup(2, Role.NORMAL, supplier);
    Database leaderDb = dbs[0];
    Database replicaDb = dbs[1];
    Index leaderIx = leaderDb.openIndex("test");
    // Wait for replica to catch up.
    fence(leaderDb, replicaDb);
    Index replicaIx = replicaDb.openIndex("test");
    Transaction txn1 = leaderDb.newTransaction();
    PrepareHandler handler = leaderDb.prepareWriter("TestHandler");
    byte[] k1 = "k1".getBytes();
    byte[] v1 = "v1".getBytes();
    leaderIx.store(txn1, k1, v1);
    if (prepareCommit) {
        handler.prepareCommit(txn1, null);
        fastAssertArrayEquals(v1, leaderIx.load(null, k1));
    } else {
        handler.prepare(txn1, null);
        try {
            leaderIx.load(null, k1);
            fail();
        } catch (LockTimeoutException e) {
        }
    }
    leaderDb.failover();
    // Replica is now the leader and should have the transaction.
    assertEquals(replicaDb, dbQueue.take());
    Transaction txn2 = txnQueue.take();
    assertNotEquals(txn1, txn2);
    assertEquals(txn1.id(), txn2.id());
    fastAssertArrayEquals(v1, replicaIx.load(txn2, k1));
    byte[] k2 = "k2".getBytes();
    byte[] v2 = "v2".getBytes();
    replicaIx.store(txn2, k2, v2);
    if (prepareCommit) {
        fastAssertArrayEquals(v1, replicaIx.load(null, k1));
    } else {
        try {
            replicaIx.load(null, k1);
            fail();
        } catch (LockTimeoutException e) {
        }
    }
    txn2.commit();
    // Wait for old leader to catch up. This will fail at first because the old leader
    // transaction is stuck.
    boolean pass = true;
    try {
        fence(replicaDb, leaderDb, true);
        pass = false;
    } catch (AssertionError e) {
    }
    assertTrue(pass);
    try {
        txn1.commit();
        fail();
    } catch (UnmodifiableReplicaException e) {
    // This will unstick the transaction.
    }
    fence(replicaDb, leaderDb);
    // Verify that the old leader observes the committed changes.
    fastAssertArrayEquals(v1, leaderIx.load(null, k1));
    fastAssertArrayEquals(v2, leaderIx.load(null, k2));
}
Also used : Index(org.cojen.tupl.Index) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) UnmodifiableReplicaException(org.cojen.tupl.UnmodifiableReplicaException) Transaction(org.cojen.tupl.Transaction) PrepareHandler(org.cojen.tupl.ext.PrepareHandler) Database(org.cojen.tupl.Database) LockTimeoutException(org.cojen.tupl.LockTimeoutException)

Example 15 with Transaction

use of org.cojen.tupl.Transaction in project Tupl by cojen.

the class DatabaseReplicatorTest method largeWrite.

@Test
public void largeWrite() throws Exception {
    Database[] dbs = startGroup(1);
    Database db = dbs[0];
    Index ix = db.openIndex("test");
    var value = new byte[100_000];
    // illegal redo op
    Arrays.fill(value, 0, value.length, (byte) 0x7f);
    byte[] key = "hello".getBytes();
    Transaction txn = db.newTransaction();
    Cursor c = ix.newCursor(txn);
    c.find(key);
    // This used to hang due to a bug. The commit index was too high, and so it wouldn't be
    // confirmed.
    c.commit(value);
    db.checkpoint();
    db = closeAndReopen(0);
    ix = db.openIndex("test");
    fastAssertArrayEquals(value, ix.load(null, key));
    db.close();
}
Also used : Transaction(org.cojen.tupl.Transaction) Database(org.cojen.tupl.Database) Index(org.cojen.tupl.Index) Cursor(org.cojen.tupl.Cursor)

Aggregations

Transaction (org.cojen.tupl.Transaction)36 Cursor (org.cojen.tupl.Cursor)12 Index (org.cojen.tupl.Index)10 LockMode (org.cojen.tupl.LockMode)8 LockResult (org.cojen.tupl.LockResult)8 Database (org.cojen.tupl.Database)6 UnpositionedCursorException (org.cojen.tupl.UnpositionedCursorException)5 IOException (java.io.IOException)4 UnmodifiableReplicaException (org.cojen.tupl.UnmodifiableReplicaException)4 PrepareHandler (org.cojen.tupl.ext.PrepareHandler)4 LinkedBlockingQueue (java.util.concurrent.LinkedBlockingQueue)3 WeakReference (java.lang.ref.WeakReference)2 ArrayList (java.util.ArrayList)2 List (java.util.List)2 TreeMap (java.util.TreeMap)2 ConcurrentSkipListMap (java.util.concurrent.ConcurrentSkipListMap)2 TimeUnit (java.util.concurrent.TimeUnit)2 Label (org.cojen.maker.Label)2 MethodMaker (org.cojen.maker.MethodMaker)2 Variable (org.cojen.maker.Variable)2