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;
}
}
}
}
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();
}
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();
}
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();
}
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();
}
Aggregations