提交 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; ...@@ -35,12 +35,15 @@ import org.h2.value.ValueLobDb;
*/ */
public class LobStorageMap implements LobStorageInterface { public class LobStorageMap implements LobStorageInterface {
private static final boolean TRACE = false; private static final boolean TRACE = true;
private final Database database; private final Database database;
private boolean init; private boolean init;
private Object nextLobIdSync = new Object();
private long nextLobId;
/** /**
* The lob metadata map. It contains the mapping from the lob id * 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). * (which is a long) to the stream store id (which is a byte array).
...@@ -190,8 +193,13 @@ public class LobStorageMap implements LobStorageInterface { ...@@ -190,8 +193,13 @@ public class LobStorageMap implements LobStorageInterface {
} }
private long generateLobId() { private long generateLobId() {
synchronized (nextLobIdSync) {
if (nextLobId == 0) {
Long id = lobMap.lastKey(); Long id = lobMap.lastKey();
return id == null ? 1 : id + 1; nextLobId = id == null ? 1 : id + 1;
}
return nextLobId++;
}
} }
@Override @Override
...@@ -299,7 +307,7 @@ public class LobStorageMap implements LobStorageInterface { ...@@ -299,7 +307,7 @@ public class LobStorageMap implements LobStorageInterface {
} }
private static void trace(String op) { private static void trace(String op) {
System.out.println("LOB " + op); System.out.println(Thread.currentThread().getName() + " LOB " + op);
} }
} }
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
*/ */
package org.h2.test.db; package org.h2.test.db;
import java.io.StringReader;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
...@@ -53,12 +54,49 @@ public class TestMultiThread extends TestBase implements Runnable { ...@@ -53,12 +54,49 @@ public class TestMultiThread extends TestBase implements Runnable {
@Override @Override
public void test() throws Exception { public void test() throws Exception {
testConcurrentLobAdd();
testConcurrentView(); testConcurrentView();
testConcurrentAlter(); testConcurrentAlter();
testConcurrentAnalyze(); testConcurrentAnalyze();
testConcurrentInsertUpdateSelect(); 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 { private void testConcurrentView() throws Exception {
if (config.mvcc) { if (config.mvcc) {
return; return;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论