Search in sources :

Example 51 with Task

use of org.h2.util.Task in project h2database by h2database.

the class TestConcurrent method test.

@Override
public void test() throws Exception {
    String url = "jdbc:h2:mem:";
    for (int i = 0; i < 50; i++) {
        final int x = i % 4;
        final Connection conn = DriverManager.getConnection(url);
        final Statement stat = conn.createStatement();
        stat.execute("create table test(id int primary key)");
        String sql = "";
        switch(x % 6) {
            case 0:
                sql = "select 1";
                break;
            case 1:
            case 2:
                sql = "delete from test";
                break;
        }
        final PreparedStatement prep = conn.prepareStatement(sql);
        Task t = new Task() {

            @Override
            public void call() throws SQLException {
                while (!conn.isClosed()) {
                    switch(x % 6) {
                        case 0:
                            prep.executeQuery();
                            break;
                        case 1:
                            prep.execute();
                            break;
                        case 2:
                            prep.executeUpdate();
                            break;
                        case 3:
                            stat.executeQuery("select 1");
                            break;
                        case 4:
                            stat.execute("select 1");
                            break;
                        case 5:
                            stat.execute("delete from test");
                            break;
                    }
                }
            }
        };
        t.execute();
        Thread.sleep(100);
        conn.close();
        SQLException e = (SQLException) t.getException();
        if (e != null) {
            if (ErrorCode.OBJECT_CLOSED != e.getErrorCode() && ErrorCode.STATEMENT_WAS_CANCELED != e.getErrorCode()) {
                throw e;
            }
        }
    }
}
Also used : Task(org.h2.util.Task) SQLException(java.sql.SQLException) Statement(java.sql.Statement) PreparedStatement(java.sql.PreparedStatement) Connection(java.sql.Connection) PreparedStatement(java.sql.PreparedStatement)

Example 52 with Task

use of org.h2.util.Task in project h2database by h2database.

the class TestMVTableEngine method testShutdownDuringLobCreation.

private void testShutdownDuringLobCreation() throws Exception {
    if (config.memory) {
        return;
    }
    deleteDb(getTestName());
    Connection conn = getConnection(getTestName());
    Statement stat = conn.createStatement();
    stat.execute("create table test(data clob) as select space(10000)");
    final PreparedStatement prep = conn.prepareStatement("set @lob = ?");
    final AtomicBoolean end = new AtomicBoolean();
    Task t = new Task() {

        @Override
        public void call() throws Exception {
            prep.setBinaryStream(1, new InputStream() {

                int len;

                @Override
                public int read() throws IOException {
                    if (len++ < 1024 * 1024 * 4) {
                        return 0;
                    }
                    end.set(true);
                    while (!stop) {
                        try {
                            Thread.sleep(1);
                        } catch (InterruptedException e) {
                        // ignore
                        }
                    }
                    return -1;
                }
            }, -1);
        }
    };
    t.execute();
    while (!end.get()) {
        Thread.sleep(1);
    }
    stat.execute("checkpoint");
    stat.execute("shutdown immediately");
    Exception ex = t.getException();
    assertNotNull(ex);
    try {
        conn.close();
    } catch (Exception e) {
    // ignore
    }
    conn = getConnection(getTestName());
    stat = conn.createStatement();
    stat.execute("shutdown defrag");
    try {
        conn.close();
    } catch (Exception e) {
    // ignore
    }
    conn = getConnection(getTestName());
    stat = conn.createStatement();
    ResultSet rs = stat.executeQuery("select * " + "from information_schema.settings " + "where name = 'info.PAGE_COUNT'");
    rs.next();
    int pages = rs.getInt(2);
    // only one lob should remain (but it is small and compressed)
    assertTrue("p:" + pages, pages < 4);
    conn.close();
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Task(org.h2.util.Task) PreparedStatement(java.sql.PreparedStatement) Statement(java.sql.Statement) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) Connection(java.sql.Connection) JdbcConnection(org.h2.jdbc.JdbcConnection) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) IOException(java.io.IOException) Savepoint(java.sql.Savepoint) SQLException(java.sql.SQLException) IOException(java.io.IOException)

Example 53 with Task

use of org.h2.util.Task in project h2database by h2database.

the class TestTransactionStore method testConcurrentAdd.

private void testConcurrentAdd() {
    MVStore s;
    s = MVStore.open(null);
    final TransactionStore ts = new TransactionStore(s);
    ts.init();
    final Random r = new Random(1);
    final AtomicInteger key = new AtomicInteger();
    final AtomicInteger failCount = new AtomicInteger();
    Task task = new Task() {

        @Override
        public void call() throws Exception {
            Transaction tx = null;
            TransactionMap<Integer, Integer> map = null;
            while (!stop) {
                int k = key.get();
                tx = ts.begin();
                map = tx.openMap("data");
                try {
                    map.put(k, r.nextInt());
                } catch (IllegalStateException e) {
                    failCount.incrementAndGet();
                // ignore and retry
                }
                tx.commit();
            }
        }
    };
    task.execute();
    Transaction tx = null;
    int count = 100000;
    TransactionMap<Integer, Integer> map = null;
    for (int i = 0; i < count; i++) {
        int k = i;
        key.set(k);
        tx = ts.begin();
        map = tx.openMap("data");
        try {
            map.put(k, r.nextInt());
        } catch (IllegalStateException e) {
            failCount.incrementAndGet();
        // ignore and retry
        }
        tx.commit();
        if (failCount.get() > 0 && i > 4000) {
            // stop earlier, if possible
            count = i;
            break;
        }
    }
    // we expect at least 10% the operations were successful
    assertTrue(failCount.toString() + " >= " + (count * 0.9), failCount.get() < count * 0.9);
    // we expect at least a few failures
    assertTrue(failCount.toString(), failCount.get() > 0);
    s.close();
}
Also used : MVStore(org.h2.mvstore.MVStore) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TransactionStore(org.h2.mvstore.db.TransactionStore) Task(org.h2.util.Task) Random(java.util.Random) Transaction(org.h2.mvstore.db.TransactionStore.Transaction) AtomicInteger(java.util.concurrent.atomic.AtomicInteger)

Example 54 with Task

use of org.h2.util.Task in project h2database by h2database.

the class TestTransactionStore method testConcurrentAddRemove.

private static void testConcurrentAddRemove() throws InterruptedException {
    MVStore s = MVStore.open(null);
    int threadCount = 3;
    final int keyCount = 2;
    final TransactionStore ts = new TransactionStore(s);
    ts.init();
    final Random r = new Random(1);
    Task[] tasks = new Task[threadCount];
    for (int i = 0; i < threadCount; i++) {
        Task task = new Task() {

            @Override
            public void call() throws Exception {
                TransactionMap<Integer, Integer> map = null;
                while (!stop) {
                    Transaction tx = ts.begin();
                    map = tx.openMap("data");
                    int k = r.nextInt(keyCount);
                    try {
                        map.remove(k);
                        map.put(k, r.nextInt());
                    } catch (IllegalStateException e) {
                    // ignore and retry
                    }
                    tx.commit();
                }
            }
        };
        task.execute();
        tasks[i] = task;
    }
    Thread.sleep(1000);
    for (Task t : tasks) {
        t.get();
    }
    s.close();
}
Also used : MVStore(org.h2.mvstore.MVStore) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TransactionStore(org.h2.mvstore.db.TransactionStore) Task(org.h2.util.Task) Random(java.util.Random) Transaction(org.h2.mvstore.db.TransactionStore.Transaction)

Example 55 with Task

use of org.h2.util.Task in project h2database by h2database.

the class TestTransactionStore method testStoreMultiThreadedReads.

private static void testStoreMultiThreadedReads() throws Exception {
    MVStore s = MVStore.open(null);
    final TransactionStore ts = new TransactionStore(s);
    ts.init();
    Transaction t = ts.begin();
    TransactionMap<Integer, Integer> mapA = t.openMap("a");
    mapA.put(1, 0);
    t.commit();
    Task task = new Task() {

        @Override
        public void call() throws Exception {
            for (int i = 0; !stop; i++) {
                Transaction tx = ts.begin();
                TransactionMap<Integer, Integer> mapA = tx.openMap("a");
                while (!mapA.tryPut(1, i)) {
                // repeat
                }
                tx.commit();
                // map B transaction
                // the other thread will get a map A uncommitted value,
                // but by the time it tries to walk back to the committed
                // value, the undoLog has changed
                tx = ts.begin();
                TransactionMap<Integer, Integer> mapB = tx.openMap("b");
                // put a new value to the map; this will cause a map B
                // undoLog entry to be created with a null pre-image value
                mapB.tryPut(i, -i);
                // this is where the real race condition occurs:
                // some other thread might get the B log entry
                // for this transaction rather than the uncommitted A log
                // entry it is expecting
                tx.commit();
            }
        }
    };
    task.execute();
    try {
        for (int i = 0; i < 10000; i++) {
            Transaction tx = ts.begin();
            mapA = tx.openMap("a");
            if (mapA.get(1) == null) {
                throw new AssertionError("key not found");
            }
            tx.commit();
        }
    } finally {
        task.get();
    }
    ts.close();
}
Also used : MVStore(org.h2.mvstore.MVStore) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TransactionStore(org.h2.mvstore.db.TransactionStore) Task(org.h2.util.Task) Transaction(org.h2.mvstore.db.TransactionStore.Transaction)

Aggregations

Task (org.h2.util.Task)71 Connection (java.sql.Connection)33 Statement (java.sql.Statement)27 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)24 PreparedStatement (java.sql.PreparedStatement)22 SQLException (java.sql.SQLException)22 MVStore (org.h2.mvstore.MVStore)20 Random (java.util.Random)18 ResultSet (java.sql.ResultSet)14 JdbcConnection (org.h2.jdbc.JdbcConnection)7 IOException (java.io.IOException)5 ServerSocket (java.net.ServerSocket)5 Socket (java.net.Socket)5 ConcurrentModificationException (java.util.ConcurrentModificationException)4 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)4 SSLServerSocket (javax.net.ssl.SSLServerSocket)4 SSLSocket (javax.net.ssl.SSLSocket)4 OutputStream (java.io.OutputStream)3 PipedInputStream (java.io.PipedInputStream)3 PipedOutputStream (java.io.PipedOutputStream)3