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

Smaller changes

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