提交 135c9b5b authored 作者: Thomas Mueller's avatar Thomas Mueller

Smaller changes

上级 c731412a
......@@ -24,7 +24,7 @@ Change Log
translation was too much out of sync. Please use the Google translation instead.
</li><li>Certain queries were not sorted if subselect queries were involved
</li><li>More bugs in the server-less multi-connection mode have been fixed:
90097 The database is read only, caches must be cleared on reconnect, etc. .
90097 The database is read only, caches must be cleared on reconnect, etc.
</li></ul>
<h2>Version 1.2.121 (2009-10-11)</h2>
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -190,6 +190,7 @@ public abstract class Command implements CommandInterface {
trace.info("slow query: " + time);
}
}
session.getDatabase().afterWriting();
}
public int executeUpdate() throws SQLException {
......
......@@ -71,7 +71,6 @@ public class CommandContainer extends Command {
prepared.checkParameters();
int updateCount = prepared.update();
prepared.trace(startTime, updateCount);
session.getDatabase().afterWriting();
return updateCount;
}
......
......@@ -42,7 +42,6 @@ public class CommandList extends Command {
public int update() throws SQLException {
int updateCount = command.executeUpdate();
executeRemaining();
session.getDatabase().afterWriting();
return updateCount;
}
......
......@@ -566,6 +566,12 @@ public class SysProperties {
*/
public static final int RECONNECT_CHECK_DELAY = getIntSetting("h2.reconnectCheckDelay", 200);
/**
* System property <code>h2.reconnectClearCache</code> (default: false).<br />
* Clear the database cache after re-connecting.
*/
public static final boolean RECONNECT_CLEAR_CACHE = getBooleanSetting("h2.reconnectClearCache", false);
/**
* System property <code>h2.redoBufferSize</code> (default: 262144).<br />
* Size of the redo buffer (used at startup when recovering).
......
......@@ -169,8 +169,8 @@ public class Database implements DataHandler {
private Properties reconnectLastLock;
private volatile long reconnectCheckNext;
private volatile boolean reconnectChangePending;
private volatile boolean allowedToRunCheckpoint;
private volatile boolean isCheckpointRunning;
private volatile boolean checkpointAllowed;
private volatile boolean checkpointRunning;
private int cacheSize;
......@@ -1810,12 +1810,14 @@ public class Database implements DataHandler {
* @throws SQLException
*/
public synchronized void clearCaches() throws SQLException {
if (fileData != null) {
fileData.getCache().clear();
fileIndex.getCache().clear();
}
if (pageStore != null) {
pageStore.getCache().clear();
if (SysProperties.RECONNECT_CLEAR_CACHE) {
if (fileData != null) {
fileData.getCache().clear();
fileIndex.getCache().clear();
}
if (pageStore != null) {
pageStore.getCache().clear();
}
}
}
......@@ -2383,11 +2385,11 @@ public class Database implements DataHandler {
if (fileLockMethod != FileLock.LOCK_SERIALIZED || readOnly || !reconnectChangePending || closing) {
return;
}
// To avoid race conditions, we already set it here
// (overlap with allowedToRunCheckpoint)
isCheckpointRunning = true;
if (!allowedToRunCheckpoint) {
isCheckpointRunning = false;
// to avoid race conditions, we already set it here
// (overlap with checkpointAllowed)
checkpointRunning = true;
if (!checkpointAllowed) {
checkpointRunning = false;
return;
}
......@@ -2398,7 +2400,7 @@ public class Database implements DataHandler {
flushIndexes(0);
checkpoint();
reconnectModified(false);
isCheckpointRunning = false;
checkpointRunning = false;
getTrace().debug("checkpoint end");
}
}
......@@ -2453,28 +2455,28 @@ public class Database implements DataHandler {
/**
* This method is called before writing to the log file.
*
* @return true if the call was successful,
* @return true if the call was successful and writing is allowed,
* false if another connection was faster
*/
public boolean beforeWriting() {
if (fileLockMethod == FileLock.LOCK_SERIALIZED) {
// To avoid race conditions, we already set it here (overlap with
// isCheckpointRunning)
allowedToRunCheckpoint = false;
while (isCheckpointRunning) {
// to avoid race conditions, we already set it here
// (overlap with checkpointRunning)
checkpointAllowed = false;
while (checkpointRunning) {
try {
Thread.sleep(10+(int) Math.random() * 10);
Thread.sleep(10 + (int) (Math.random() * 10));
} catch (Exception e) {
// ignore
}
}
boolean allowedToWrite = reconnectModified(true);
if (!allowedToWrite) {
boolean writingAllowed = reconnectModified(true);
if (!writingAllowed) {
// make sure the next call to isReconnectNeeded() returns yes
reconnectCheckNext = System.currentTimeMillis() - 1;
reconnectLastLock = null;
}
return allowedToWrite;
return writingAllowed;
}
return true;
}
......@@ -2483,7 +2485,7 @@ public class Database implements DataHandler {
* This method is called after updates are finished.
*/
public void afterWriting() {
allowedToRunCheckpoint = true;
checkpointAllowed = true;
}
/**
......
......@@ -1134,7 +1134,10 @@ public class Session extends SessionWithState {
newSession.sessionState = sessionState;
newSession.recreateSessionState();
database.clearCaches();
while (write && !database.beforeWriting()) {
if (write) {
while (!database.beforeWriting()) {
// wait until we are allowed to write
}
}
return newSession;
}
......
......@@ -88,4 +88,5 @@ public interface SessionInterface {
* @return the new connection
*/
SessionInterface reconnect(boolean write) throws SQLException;
}
......@@ -695,18 +695,14 @@ public class TableFilter implements ColumnResolver {
}
/**
* Returns if there are in(...) comparisons involved
* Are there any index conditions that involve IN(...).
*
* @see Comparison#IN_LIST
* @see Comparison#IN_QUERY
*
* @return if there are in(...) comparisons involved
* @return whether there are IN(...) comparisons
*/
public boolean hasInComparisons() {
for (int i = 0; i < indexConditions.size(); i++) {
if ((indexConditions.get(i).getCompareType() == Comparison.IN_QUERY)
||
(indexConditions.get(i).getCompareType() == Comparison.IN_LIST)) {
for (IndexCondition cond : indexConditions) {
int compareType = cond.getCompareType();
if (compareType == Comparison.IN_QUERY || compareType == Comparison.IN_LIST) {
return true;
}
}
......
......@@ -717,7 +717,7 @@ public abstract class TestBase {
* @param condition the condition
* @throws AssertionError if the condition is false
*/
protected void assertTrue(boolean condition) {
public void assertTrue(boolean condition) {
assertTrue("Expected: true got: false", condition);
}
......
......@@ -10,7 +10,6 @@ import java.io.File;
import java.io.StringReader;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
......@@ -883,21 +882,17 @@ public class TestCases extends TestBase {
}
private void testOrderByWithSubselect() throws SQLException {
Connection c = DriverManager.getConnection("jdbc:h2:mem:testdb");
Statement s = c.createStatement();
s.execute("create table master(id number primary key, name varchar2(30));");
s.execute("create table detail(id number references master(id), location varchar2(30));");
s.execute("Insert into master values(1,'a');");
s.execute("Insert into master values(2,'b');");
s.execute("Insert into master values(3,'c');");
s.execute("commit;");
s.execute("Insert into detail values(1,'a');");
s.execute("Insert into detail values(2,'b');");
s.execute("Insert into detail values(3,'c');");
s.execute("commit;");
ResultSet rs = s.executeQuery(
deleteDb("cases");
Connection conn = getConnection("cases");
Statement stat = conn.createStatement();
stat.execute("create table master(id number primary key, name varchar2(30));");
stat.execute("create table detail(id number references master(id), location varchar2(30));");
stat.execute("Insert into master values(1,'a'), (2,'b'), (3,'c');");
stat.execute("Insert into detail values(1,'a'), (2,'b'), (3,'c');");
ResultSet rs = stat.executeQuery(
"select master.id, master.name " +
"from master " +
"where master.id in (select detail.id from detail) " +
......@@ -909,7 +904,7 @@ public class TestCases extends TestBase {
assertTrue(rs.next());
assertEquals(3, rs.getInt(1));
c.close();
conn.close();
}
}
......@@ -403,11 +403,8 @@ public class TestFileLockSerialized extends TestBase {
final String url = "jdbc:h2:" + baseDir + "/fileLockSerialized;FILE_LOCK=SERIALIZED;OPEN_NEW=TRUE;CACHE_SIZE=" + cacheSizeKb;
final boolean[] importFinished = { false };
final boolean[] updateFinished = { false };
final boolean[] testFinished = { false };
final Exception[] ex = new Exception[1];
new Thread() {
final Thread importUpdate = new Thread() {
public void run() {
try {
Connection conn = DriverManager.getConnection(url);
......@@ -419,17 +416,17 @@ public class TestFileLockSerialized extends TestBase {
importFinished[0] = true;
Thread.sleep(5000);
stat.execute("update test set id2=999 where id=500");
updateFinished[0] = true;
conn.close();
} catch (Exception e) {
e.printStackTrace();
ex[0] = e;
} finally {
importFinished[0] = true;
}
}
};
importUpdate.start();
}.start();
new Thread() {
Thread select = new Thread() {
public void run() {
try {
Connection conn = DriverManager.getConnection(url);
......@@ -442,26 +439,21 @@ public class TestFileLockSerialized extends TestBase {
assertTrue(rs.next());
assertEquals(500, rs.getInt(1));
rs.close();
while (!updateFinished[0]) {
Thread.sleep(100);
}
importUpdate.join();
Thread.sleep(1000);
rs = stat.executeQuery("select id2 from test where id=500");
assertTrue(rs.next());
assertEquals(999, rs.getInt(1));
rs.close();
conn.close();
testFinished[0] = true;
} catch (Exception e) {
e.printStackTrace();
ex[0] = e;
}
}
}.start();
while ((ex[0] == null) && (!testFinished[0])) {
Thread.sleep(10);
}
};
select.start();
importUpdate.join();
select.join();
if (ex[0] != null) {
throw ex[0];
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论