private void testCancelReuse(Connection conn) throws Exception {
   conn.createStatement().execute("CREATE ALIAS SLEEP FOR \"java.lang.Thread.sleep\"");
   // sleep for 10 seconds
   final PreparedStatement prep =
       conn.prepareStatement("SELECT SLEEP(?) FROM SYSTEM_RANGE(1, 10000) LIMIT ?");
   prep.setInt(1, 1);
   prep.setInt(2, 10000);
   Task t =
       new Task() {
         @Override
         public void call() throws SQLException {
           prep.execute();
         }
       };
   t.execute();
   Thread.sleep(100);
   prep.cancel();
   SQLException e = (SQLException) t.getException();
   assertTrue(e != null);
   assertEquals(ErrorCode.STATEMENT_WAS_CANCELED, e.getErrorCode());
   prep.setInt(1, 1);
   prep.setInt(2, 1);
   ResultSet rs = prep.executeQuery();
   assertTrue(rs.next());
   assertEquals(0, rs.getInt(1));
   assertFalse(rs.next());
 }
 private void testConcurrentIterate() {
   MVStore s = new MVStore.Builder().pageSplitSize(3).open();
   s.setVersionsToKeep(100);
   final MVMap<Integer, Integer> map = s.openMap("test");
   final int len = 10;
   final Random r = new Random();
   Task t =
       new Task() {
         @Override
         public void call() throws Exception {
           while (!stop) {
             int x = r.nextInt(len);
             if (r.nextBoolean()) {
               map.remove(x);
             } else {
               map.put(x, r.nextInt(100));
             }
           }
         }
       };
   t.execute();
   for (int k = 0; k < 10000; k++) {
     Iterator<Integer> it = map.keyIterator(r.nextInt(len));
     long old = s.getCurrentVersion();
     s.commit();
     while (map.getVersion() == old) {
       Thread.yield();
     }
     while (it.hasNext()) {
       it.next();
     }
   }
   t.get();
   s.close();
 }
 private void testConcurrentStoreAndRemoveMap() throws InterruptedException {
   String fileName = "memFS:testConcurrentStoreAndRemoveMap.h3";
   final MVStore s = openStore(fileName);
   int count = 200;
   for (int i = 0; i < count; i++) {
     MVMap<Integer, Integer> m = s.openMap("d" + i);
     m.put(1, 1);
   }
   final AtomicInteger counter = new AtomicInteger();
   Task task =
       new Task() {
         @Override
         public void call() throws Exception {
           while (!stop) {
             counter.incrementAndGet();
             s.commit();
           }
         }
       };
   task.execute();
   Thread.sleep(1);
   for (int i = 0; i < count || counter.get() < count; i++) {
     MVMap<Integer, Integer> m = s.openMap("d" + i);
     m.put(1, 10);
     s.removeMap(m);
     if (task.isFinished()) {
       break;
     }
   }
   task.get();
   s.close();
   FileUtils.deleteRecursive("memFS:", false);
 }
 /** Test the concurrent map implementation. */
 private void testConcurrentMap() throws InterruptedException {
   final MVStore s = openStore(null);
   final MVMap<Integer, Integer> m =
       s.openMap("data", new MVMapConcurrent.Builder<Integer, Integer>());
   final int size = 20;
   final Random rand = new Random(1);
   Task task =
       new Task() {
         @Override
         public void call() throws Exception {
           try {
             while (!stop) {
               if (rand.nextBoolean()) {
                 m.put(rand.nextInt(size), 1);
               } else {
                 m.remove(rand.nextInt(size));
               }
               m.get(rand.nextInt(size));
               m.firstKey();
               m.lastKey();
               m.ceilingKey(5);
               m.floorKey(5);
               m.higherKey(5);
               m.lowerKey(5);
               for (Iterator<Integer> it = m.keyIterator(null); it.hasNext(); ) {
                 it.next();
               }
             }
           } catch (Exception e) {
             e.printStackTrace();
           }
         }
       };
   task.execute();
   Thread.sleep(1);
   for (int j = 0; j < 100; j++) {
     for (int i = 0; i < 100; i++) {
       if (rand.nextBoolean()) {
         m.put(rand.nextInt(size), 2);
       } else {
         m.remove(rand.nextInt(size));
       }
       m.get(rand.nextInt(size));
     }
     s.commit();
     Thread.sleep(1);
   }
   task.get();
   s.close();
 }
 private void testConcurrentOnlineBackup() throws Exception {
   String fileName = getBaseDir() + "/onlineBackup.h3";
   String fileNameRestore = getBaseDir() + "/onlineRestore.h3";
   final MVStore s = openStore(fileName);
   final MVMap<Integer, byte[]> map = s.openMap("test");
   final Random r = new Random();
   Task t =
       new Task() {
         @Override
         public void call() throws Exception {
           while (!stop) {
             for (int i = 0; i < 10; i++) {
               map.put(i, new byte[100 * r.nextInt(100)]);
             }
             s.commit();
             map.clear();
             s.commit();
             long len = s.getFileStore().size();
             if (len > 1024 * 1024) {
               // slow down writing a lot
               Thread.sleep(200);
             } else if (len > 20 * 1024) {
               // slow down writing
               Thread.sleep(20);
             }
           }
         }
       };
   t.execute();
   for (int i = 0; i < 10; i++) {
     // System.out.println("test " + i);
     s.setReuseSpace(false);
     byte[] buff = readFileSlowly(s.getFileStore().getFile(), s.getFileStore().size());
     s.setReuseSpace(true);
     FileOutputStream out = new FileOutputStream(fileNameRestore);
     out.write(buff);
     MVStore s2 = openStore(fileNameRestore);
     MVMap<Integer, byte[]> test = s2.openMap("test");
     for (Integer k : test.keySet()) {
       test.get(k);
     }
     s2.close();
     // let it compact
     Thread.sleep(10);
   }
   t.get();
   s.close();
 }
  private void testCases() throws Exception {
    deleteDb("rowLocks");
    c1 = getConnection("rowLocks;MVCC=TRUE");
    s1 = c1.createStatement();
    s1.execute("SET LOCK_TIMEOUT 10000");
    s1.execute("CREATE TABLE TEST AS SELECT X ID, 'Hello' NAME FROM SYSTEM_RANGE(1, 3)");
    c1.commit();
    c1.setAutoCommit(false);
    s1.execute("UPDATE TEST SET NAME='Hallo' WHERE ID=1");

    c2 = getConnection("rowLocks");
    c2.setAutoCommit(false);
    s2 = c2.createStatement();

    assertEquals("Hallo", getSingleValue(s1, "SELECT NAME FROM TEST WHERE ID=1"));
    assertEquals("Hello", getSingleValue(s2, "SELECT NAME FROM TEST WHERE ID=1"));

    s2.execute("UPDATE TEST SET NAME='Hallo' WHERE ID=2");
    assertThrows(ErrorCode.LOCK_TIMEOUT_1, s2)
        .executeUpdate("UPDATE TEST SET NAME='Hi' WHERE ID=1");
    c1.commit();
    c2.commit();

    assertEquals("Hallo", getSingleValue(s1, "SELECT NAME FROM TEST WHERE ID=1"));
    assertEquals("Hallo", getSingleValue(s2, "SELECT NAME FROM TEST WHERE ID=1"));

    s2.execute("UPDATE TEST SET NAME='H1' WHERE ID=1");
    Task task =
        new Task() {
          @Override
          public void call() throws SQLException {
            s1.execute("UPDATE TEST SET NAME='H2' WHERE ID=1");
          }
        };
    task.execute();
    Thread.sleep(100);
    c2.commit();
    task.get();
    c1.commit();
    assertEquals("H2", getSingleValue(s1, "SELECT NAME FROM TEST WHERE ID=1"));
    assertEquals("H2", getSingleValue(s2, "SELECT NAME FROM TEST WHERE ID=1"));

    c1.close();
    c2.close();
  }
Exemple #7
0
 private void testStartWebServerWithConnection() throws Exception {
   String old = System.getProperty(SysProperties.H2_BROWSER);
   try {
     System.setProperty(
         SysProperties.H2_BROWSER, "call:" + TestWeb.class.getName() + ".openBrowser");
     Server.openBrowser("testUrl");
     assertEquals("testUrl", lastUrl);
     String oldUrl = lastUrl;
     final Connection conn = getConnection("testWeb");
     Task t =
         new Task() {
           public void call() throws Exception {
             Server.startWebServer(conn);
           }
         };
     t.execute();
     for (int i = 0; lastUrl == oldUrl; i++) {
       if (i > 100) {
         throw new Exception("Browser not started");
       }
       Thread.sleep(100);
     }
     String url = lastUrl;
     WebClient client = new WebClient();
     client.readSessionId(url);
     url = client.getBaseUrl(url);
     try {
       client.get(url, "logout.do");
     } catch (Exception e) {
       // the server stops on logout
     }
     t.get();
   } finally {
     if (old != null) {
       System.setProperty(SysProperties.H2_BROWSER, old);
     } else {
       System.clearProperty(SysProperties.H2_BROWSER);
     }
     deleteDb("testWeb");
   }
 }
 private void testConcurrentStoreAndClose() throws InterruptedException {
   String fileName = "memFS:testConcurrentStoreAndClose";
   for (int i = 0; i < 10; i++) {
     FileUtils.delete(fileName);
     final MVStore s = openStore(fileName);
     final AtomicInteger counter = new AtomicInteger();
     Task task =
         new Task() {
           @Override
           public void call() throws Exception {
             while (!stop) {
               s.setStoreVersion(counter.incrementAndGet());
               s.commit();
             }
           }
         };
     task.execute();
     while (counter.get() < 5) {
       Thread.sleep(1);
     }
     try {
       s.close();
       // sometimes closing works, in which case
       // storing must fail at some point (not necessarily
       // immediately)
       for (int x = counter.get(), y = x; x <= y + 2; x++) {
         Thread.sleep(1);
       }
       Exception e = task.getException();
       assertEquals(DataUtils.ERROR_CLOSED, DataUtils.getErrorCode(e.getMessage()));
     } catch (IllegalStateException e) {
       // sometimes storing works, in which case
       // closing must fail
       assertEquals(DataUtils.ERROR_WRITING_FAILED, DataUtils.getErrorCode(e.getMessage()));
       task.get();
     }
     s.close();
   }
   FileUtils.deleteRecursive("memFS:", false);
 }
 private void testTriggerDeadlock() throws Exception {
   final Connection conn, conn2;
   final Statement stat, stat2;
   conn = getConnection("trigger");
   conn2 = getConnection("trigger");
   stat = conn.createStatement();
   stat2 = conn2.createStatement();
   stat.execute("create table test(id int) as select 1");
   stat.execute("create table test2(id int) as select 1");
   stat.execute(
       "create trigger test_u before update on test2 "
           + "for each row call \""
           + DeleteTrigger.class.getName()
           + "\"");
   conn.setAutoCommit(false);
   conn2.setAutoCommit(false);
   stat2.execute("update test set id = 2");
   Task task =
       new Task() {
         @Override
         public void call() throws Exception {
           Thread.sleep(300);
           stat2.execute("update test2 set id = 4");
         }
       };
   task.execute();
   Thread.sleep(100);
   try {
     stat.execute("update test2 set id = 3");
     task.get();
   } catch (SQLException e) {
     assertEquals(ErrorCode.LOCK_TIMEOUT_1, e.getErrorCode());
   }
   conn2.rollback();
   conn.rollback();
   stat.execute("drop table test");
   stat.execute("drop table test2");
   conn.close();
   conn2.close();
 }
Exemple #10
0
 /**
  * Get a writer to update the Clob. This is only supported for new, empty Clob objects that were
  * created with Connection.createClob() or createNClob(). The Clob is created in a separate
  * thread, and the object is only updated when Writer.close() is called. The position must be 1,
  * meaning the whole Clob data is set.
  *
  * @param pos where to start writing (the first character is at position 1)
  * @return a writer
  */
 public Writer setCharacterStream(long pos) throws SQLException {
   try {
     if (isDebugEnabled()) {
       debugCodeCall("setCharacterStream(" + pos + ");");
     }
     checkClosed();
     if (pos != 1) {
       throw DbException.getInvalidValueException("pos", pos);
     }
     if (value.getPrecision() != 0) {
       throw DbException.getInvalidValueException("length", value.getPrecision());
     }
     final JdbcConnection c = conn;
     // PipedReader / PipedWriter are a lot slower
     // than PipedInputStream / PipedOutputStream
     // (Sun/Oracle Java 1.6.0_20)
     final PipedInputStream in = new PipedInputStream();
     final Task task =
         new Task() {
           public void call() {
             value = c.createClob(IOUtils.getReader(in), -1);
           }
         };
     PipedOutputStream out =
         new PipedOutputStream(in) {
           public void close() throws IOException {
             super.close();
             try {
               task.get();
             } catch (Exception e) {
               throw DbException.convertToIOException(e);
             }
           }
         };
     task.execute();
     return IOUtils.getBufferedWriter(out);
   } catch (Exception e) {
     throw logAndConvert(e);
   }
 }
 private void testConcurrentRead() throws InterruptedException {
   final MVStore s = openStore(null);
   final MVMap<Integer, Integer> m = s.openMap("data");
   final int size = 3;
   int x = (int) s.getCurrentVersion();
   for (int i = 0; i < size; i++) {
     m.put(i, x);
   }
   s.commit();
   Task task =
       new Task() {
         @Override
         public void call() throws Exception {
           while (!stop) {
             long v = s.getCurrentVersion() - 1;
             Map<Integer, Integer> old = m.openVersion(v);
             for (int i = 0; i < size; i++) {
               Integer x = old.get(i);
               if (x == null || (int) v != x) {
                 Map<Integer, Integer> old2 = m.openVersion(v);
                 throw new AssertionError(x + "<>" + v + " at " + i + " " + old2);
               }
             }
           }
         }
       };
   task.execute();
   Thread.sleep(1);
   for (int j = 0; j < 100; j++) {
     x = (int) s.getCurrentVersion();
     for (int i = 0; i < size; i++) {
       m.put(i, x);
     }
     s.commit();
     Thread.sleep(1);
   }
   task.get();
   s.close();
 }
  private void testConcurrentFree() throws InterruptedException {
    String fileName = "memFS:testConcurrentFree.h3";
    for (int test = 0; test < 10; test++) {
      FileUtils.delete(fileName);
      final MVStore s1 = new MVStore.Builder().fileName(fileName).autoCommitDisabled().open();
      s1.setRetentionTime(0);
      final int count = 200;
      for (int i = 0; i < count; i++) {
        MVMap<Integer, Integer> m = s1.openMap("d" + i);
        m.put(1, 1);
        if (i % 2 == 0) {
          s1.commit();
        }
      }
      s1.close();
      final MVStore s = new MVStore.Builder().fileName(fileName).autoCommitDisabled().open();
      s.setRetentionTime(0);
      final ArrayList<MVMap<Integer, Integer>> list = New.arrayList();
      for (int i = 0; i < count; i++) {
        MVMap<Integer, Integer> m = s.openMap("d" + i);
        list.add(m);
      }

      final AtomicInteger counter = new AtomicInteger();
      Task task =
          new Task() {
            @Override
            public void call() throws Exception {
              while (!stop) {
                int x = counter.getAndIncrement();
                if (x >= count) {
                  break;
                }
                MVMap<Integer, Integer> m = list.get(x);
                m.clear();
                s.removeMap(m);
              }
            }
          };
      task.execute();
      Thread.sleep(1);
      while (true) {
        int x = counter.getAndIncrement();
        if (x >= count) {
          break;
        }
        MVMap<Integer, Integer> m = list.get(x);
        m.clear();
        s.removeMap(m);
        if (x % 5 == 0) {
          s.commit();
        }
      }
      task.get();
      s.commit();

      MVMap<String, String> meta = s.getMetaMap();
      int chunkCount = 0;
      for (String k : meta.keyList()) {
        if (k.startsWith("chunk.")) {
          chunkCount++;
        }
      }
      assertEquals(1, chunkCount);
      s.close();
    }
    FileUtils.deleteRecursive("memFS:", false);
  }
 private void testConcurrentWrite(final AtomicInteger detected, final AtomicInteger notDetected)
     throws InterruptedException {
   final MVStore s = openStore(null);
   final MVMap<Integer, Integer> m = s.openMap("data");
   final int size = 20;
   final Random rand = new Random(1);
   Task task =
       new Task() {
         @Override
         public void call() throws Exception {
           while (!stop) {
             try {
               if (rand.nextBoolean()) {
                 m.put(rand.nextInt(size), 1);
               } else {
                 m.remove(rand.nextInt(size));
               }
               m.get(rand.nextInt(size));
             } catch (ConcurrentModificationException e) {
               detected.incrementAndGet();
             } catch (NegativeArraySizeException e) {
               notDetected.incrementAndGet();
             } catch (ArrayIndexOutOfBoundsException e) {
               notDetected.incrementAndGet();
             } catch (IllegalArgumentException e) {
               notDetected.incrementAndGet();
             } catch (NullPointerException e) {
               notDetected.incrementAndGet();
             }
           }
         }
       };
   task.execute();
   Thread.sleep(1);
   for (int j = 0; j < 10; j++) {
     for (int i = 0; i < 10; i++) {
       try {
         if (rand.nextBoolean()) {
           m.put(rand.nextInt(size), 2);
         } else {
           m.remove(rand.nextInt(size));
         }
         m.get(rand.nextInt(size));
       } catch (ConcurrentModificationException e) {
         detected.incrementAndGet();
       } catch (NegativeArraySizeException e) {
         notDetected.incrementAndGet();
       } catch (ArrayIndexOutOfBoundsException e) {
         notDetected.incrementAndGet();
       } catch (IllegalArgumentException e) {
         notDetected.incrementAndGet();
       } catch (NullPointerException e) {
         notDetected.incrementAndGet();
       }
     }
     s.commit();
     Thread.sleep(1);
   }
   task.get();
   s.close();
 }
  private void testStopWhileCommitting() throws Exception {
    String fileName = getBaseDir() + "/testStopWhileCommitting.h3";
    FileUtils.delete(fileName);
    Random r = new Random(0);

    for (int i = 0; i < 10; ) {
      MVStore s;
      TransactionStore ts;
      Transaction tx;
      TransactionMap<Integer, String> m;

      s = MVStore.open(fileName);
      ts = new TransactionStore(s);
      tx = ts.begin();
      s.setReuseSpace(false);
      m = tx.openMap("test");
      final String value = "x" + i;
      for (int j = 0; j < 1000; j++) {
        m.put(j, value);
      }
      final AtomicInteger state = new AtomicInteger();
      final MVStore store = s;
      final MVMap<Integer, String> other = s.openMap("other");
      Task task =
          new Task() {

            @Override
            public void call() throws Exception {
              for (int i = 0; !stop; i++) {
                state.set(i);
                other.put(i, value);
                store.commit();
              }
            }
          };
      task.execute();
      // wait for the task to start
      while (state.get() < 1) {
        Thread.yield();
      }
      // commit while writing in the task
      tx.commit();
      // wait for the task to stop
      task.get();
      store.close();
      s = MVStore.open(fileName);
      // roll back a bit, until we have some undo log entries
      assertTrue(s.hasMap("undoLog"));
      for (int back = 0; back < 100; back++) {
        int minus = r.nextInt(10);
        s.rollbackTo(Math.max(0, s.getCurrentVersion() - minus));
        MVMap<?, ?> undo = s.openMap("undoLog");
        if (undo.size() > 0) {
          break;
        }
      }
      ts = new TransactionStore(s);
      List<Transaction> list = ts.getOpenTransactions();
      if (list.size() != 0) {
        tx = list.get(0);
        if (tx.getStatus() == Transaction.STATUS_COMMITTING) {
          i++;
        }
      }
      s.close();
      FileUtils.delete(fileName);
      assertFalse(FileUtils.exists(fileName));
    }
  }