提交 5ae2eac5 authored 作者: Thomas Mueller's avatar Thomas Mueller

Multi-Version Concurrency (MVCC) may no longer be used when using the…

Multi-Version Concurrency (MVCC) may no longer be used when using the multi-threaded kernel feature (MULTI_THREADED).
上级 ceb1858a
......@@ -132,7 +132,6 @@ public class Database implements DataHandler {
private boolean logIndexChanges;
private int logLevel = 1;
private int maxLengthInplaceLob = Constants.DEFAULT_MAX_LENGTH_INPLACE_LOB;
private long biggestFileSize;
private int allowLiterals = Constants.DEFAULT_ALLOW_LITERALS;
private int powerOffCount = initialPowerOffCount;
......@@ -198,6 +197,7 @@ public class Database implements DataHandler {
this.recovery = true;
}
this.multiVersion = ci.removeProperty("MVCC", false);
checkMultiThreadedAllowed();
boolean closeAtVmShutdown = ci.removeProperty("DB_CLOSE_ON_EXIT", true);
int traceLevelFile = ci.getIntProperty(SetTypes.TRACE_LEVEL_FILE, TraceSystem.DEFAULT_TRACE_LEVEL_FILE);
int traceLevelSystemOut = ci.getIntProperty(SetTypes.TRACE_LEVEL_SYSTEM_OUT,
......@@ -1749,7 +1749,6 @@ public class Database implements DataHandler {
case Constants.LOCK_MODE_READ_COMMITTED:
case Constants.LOCK_MODE_TABLE:
case Constants.LOCK_MODE_TABLE_GC:
case Constants.LOCK_MODE_ROW:
break;
default:
throw Message.getInvalidValueException("lock mode", "" + lockMode);
......@@ -1858,32 +1857,19 @@ public class Database implements DataHandler {
public void setLobCompressionAlgorithm(String stringValue) {
this.lobCompressionAlgorithm = stringValue;
}
/**
* Called when the size if the data or index file has been changed. The log
* file size is at least 10% of the largest file.
* Called when the size if the data or index file has been changed.
*
* @param length the new file size
*/
public void notifyFileSize(long length) {
if (length > biggestFileSize) {
biggestFileSize = length;
setMaxLogSize(0);
}
// ignore
}
public synchronized void setMaxLogSize(long value) {
long minLogSize = biggestFileSize / Constants.LOG_SIZE_DIVIDER;
minLogSize = Math.max(value, minLogSize);
long currentLogSize = getLog().getMaxLogSize();
if (minLogSize > currentLogSize || (value > 0 && minLogSize > value)) {
// works for currentLogSize <= 0 as well
value = minLogSize;
}
if (value > 0) {
getLog().setMaxLogSize(value);
}
}
getLog().setMaxLogSize(value);
}
public void setAllowLiterals(int value) {
this.allowLiterals = value;
......@@ -1970,10 +1956,19 @@ public class Database implements DataHandler {
return multiThreaded;
}
public void setMultiThreaded(boolean multiThreaded) {
public void setMultiThreaded(boolean multiThreaded) throws SQLException {
this.multiThreaded = multiThreaded;
checkMultiThreadedAllowed();
}
private void checkMultiThreadedAllowed() throws SQLException {
if (multiThreaded && multiVersion) {
multiVersion = false;
throw Message.getSQLException(ErrorCode.CANNOT_CHANGE_SETTING_WHEN_OPEN_1, "MVCC & MULTI_THREADED");
}
}
public void setMaxOperationMemory(int maxOperationMemory) {
this.maxOperationMemory = maxOperationMemory;
}
......
/*
* Copyright 2004-2008 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.test.mvcc;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.h2.test.TestBase;
/**
* Multi-threaded MVCC (multi version concurrency) test cases.
*/
public class TestMvccMultiThreaded extends TestBase {
public void test() throws Exception {
if (!config.mvcc) {
return;
}
if (config.mvcc) {
// not supported at this time
return;
}
deleteDb("mvccMultiThreaded");
int len = 2;
final Connection[] connList = new Connection[len];
for (int i = 0; i < len; i++) {
connList[i] = getConnection("mvccMultiThreaded;MULTI_THREADED=TRUE");
}
Connection conn = connList[0];
conn.createStatement().execute("create table test(id int primary key, value int)");
conn.createStatement().execute("insert into test values(0, 0)");
final SQLException[] ex = new SQLException[1];
final int count = 1000;
Thread[] threads = new Thread[len];
for (int i = 0; i < len; i++) {
final int x = i;
threads[i] = new Thread() {
public void run() {
for (int a = 0; a < count; a++) {
try {
connList[x].createStatement().execute("update test set value=value+1");
} catch (SQLException e) {
ex[0] = e;
}
}
}
};
threads[i].start();
}
for (int i = 0; i < len; i++) {
threads[i].join();
}
if (ex[0] != null) {
throw ex[0];
}
ResultSet rs = conn.createStatement().executeQuery("select value from test");
rs.next();
assertEquals(count * len, rs.getInt(1));
for (int i = 0; i < len; i++) {
connList[i].close();
}
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论