提交 581f5126 authored 作者: Thomas Mueller's avatar Thomas Mueller

Issue 565: MVStore: concurrently adding LOB objects (with MULTI_THREADED option)…

Issue 565: MVStore: concurrently adding LOB objects (with MULTI_THREADED option) resulted in a NullPointerException. 
上级 6097f4d0
......@@ -35,12 +35,15 @@ import org.h2.value.ValueLobDb;
*/
public class LobStorageMap implements LobStorageInterface {
private static final boolean TRACE = false;
private static final boolean TRACE = true;
private final Database database;
private boolean init;
private Object nextLobIdSync = new Object();
private long nextLobId;
/**
* The lob metadata map. It contains the mapping from the lob id
* (which is a long) to the stream store id (which is a byte array).
......@@ -190,8 +193,13 @@ public class LobStorageMap implements LobStorageInterface {
}
private long generateLobId() {
synchronized (nextLobIdSync) {
if (nextLobId == 0) {
Long id = lobMap.lastKey();
return id == null ? 1 : id + 1;
nextLobId = id == null ? 1 : id + 1;
}
return nextLobId++;
}
}
@Override
......@@ -299,7 +307,7 @@ public class LobStorageMap implements LobStorageInterface {
}
private static void trace(String op) {
System.out.println("LOB " + op);
System.out.println(Thread.currentThread().getName() + " LOB " + op);
}
}
......@@ -6,6 +6,7 @@
*/
package org.h2.test.db;
import java.io.StringReader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
......@@ -53,12 +54,49 @@ public class TestMultiThread extends TestBase implements Runnable {
@Override
public void test() throws Exception {
testConcurrentLobAdd();
testConcurrentView();
testConcurrentAlter();
testConcurrentAnalyze();
testConcurrentInsertUpdateSelect();
}
private void testConcurrentLobAdd() throws Exception {
String db = "concurrentLobAdd";
deleteDb(db);
final String url = getURL(db + ";MULTI_THREADED=1", true);
Connection conn = getConnection(url);
Statement stat = conn.createStatement();
stat.execute("create table test(id identity, data clob)");
Task[] tasks = new Task[2];
for (int i = 0; i < tasks.length; i++) {
Task t = new Task() {
@Override
public void call() throws Exception {
Connection c2 = getConnection(url);
PreparedStatement p2 = c2
.prepareStatement("insert into test(data) values(?)");
try {
while (!stop) {
p2.setCharacterStream(1, new StringReader(new String(
new char[10 * 1024])));
p2.execute();
}
} finally {
c2.close();
}
}
};
tasks[i] = t;
t.execute();
}
Thread.sleep(500);
for (Task t : tasks) {
t.get();
}
conn.close();
}
private void testConcurrentView() throws Exception {
if (config.mvcc) {
return;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论