提交 8221deaa authored 作者: Thomas Mueller's avatar Thomas Mueller

New system property h2.selectForUpdateMvcc, the default is false (the feature is disabled).

上级 08d3f1a5
...@@ -18,7 +18,9 @@ Change Log ...@@ -18,7 +18,9 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul><li>Profiler: improved message if there was no stack trace. <ul><li>New system property h2.selectForUpdateMvcc, the default is false (the feature is disabled).
When enabled, SELECT ... FOR UPDATE only locks the selected rows in the MVCC mode.
</li><li>Profiler: improved message if there was no stack trace.
</li><li>The H2 Console can now be used within another application, in a frame or iframe. Issue 197. </li><li>The H2 Console can now be used within another application, in a frame or iframe. Issue 197.
</li><li>Recover tool: the statistics section now includes page type counts again. </li><li>Recover tool: the statistics section now includes page type counts again.
</li><li>Queries with multiple IN(...) conditions sometimes return the wrong results when there was a multi-column index for the column. </li><li>Queries with multiple IN(...) conditions sometimes return the wrong results when there was a multi-column index for the column.
......
...@@ -23,9 +23,10 @@ See also <a href="build.html#providing_patches">Providing Patches</a>. ...@@ -23,9 +23,10 @@ See also <a href="build.html#providing_patches">Providing Patches</a>.
</p> </p>
<h2>Version 1.3.x: Planned Changes</h2> <h2>Version 1.3.x: Planned Changes</h2>
<ul><li>Lob storage: enable the system property h2.lobInDatabase by default. <ul><li>Enable h2.lobInDatabase (store CLOB and BLOB in the database file).
</li><li>Automatic ANALYZE: set the system property h2.analyzeAuto to 2000. </li><li>Set h2.analyzeAuto to 2000 (automatic ANALYZE).
</li><li>Enable h2.functionsInSchema. </li><li>Enable h2.functionsInSchema (allow to store functions in a schema).
</li><li>Enable h2.selectForUpdateMvcc (MVCC and SELECT FOR UPDATE).
</li></ul> </li></ul>
<h2>Priority 1</h2> <h2>Priority 1</h2>
...@@ -38,7 +39,6 @@ See also <a href="build.html#providing_patches">Providing Patches</a>. ...@@ -38,7 +39,6 @@ See also <a href="build.html#providing_patches">Providing Patches</a>.
<h2>Priority 2</h2> <h2>Priority 2</h2>
<ul><li>Improve test code coverage. <ul><li>Improve test code coverage.
</li><li>MVCC: select for update should only lock the selected rows.
</li><li>Test multi-threaded in-memory db access </li><li>Test multi-threaded in-memory db access
</li><li>Option to shutdown all the running servers (on the same VM). </li><li>Option to shutdown all the running servers (on the same VM).
</li><li>Full outer joins. </li><li>Full outer joins.
...@@ -468,6 +468,8 @@ See also <a href="build.html#providing_patches">Providing Patches</a>. ...@@ -468,6 +468,8 @@ See also <a href="build.html#providing_patches">Providing Patches</a>.
</li><li>Database file name suffix: a way to use no or a different suffix (for example using a slash). </li><li>Database file name suffix: a way to use no or a different suffix (for example using a slash).
</li><li>Database file name suffix: should only have one dot by default. Example: .h2db </li><li>Database file name suffix: should only have one dot by default. Example: .h2db
</li><li>Issue 196: Function based indexes </li><li>Issue 196: Function based indexes
</li><li>Fix the disk space leak (killing the process at the exact right moment will increase
the disk space usage; this space is not re-used). See TestDiskSpaceLeak.java
</li></ul> </li></ul>
<h2>Not Planned</h2> <h2>Not Planned</h2>
......
...@@ -73,7 +73,7 @@ public class Select extends Query { ...@@ -73,7 +73,7 @@ public class Select extends Query {
private HashMap<Expression, Object> currentGroup; private HashMap<Expression, Object> currentGroup;
private int havingIndex; private int havingIndex;
private boolean isGroupQuery, isGroupSortedQuery; private boolean isGroupQuery, isGroupSortedQuery;
private boolean isForUpdate; private boolean isForUpdate, isForUpdateMvcc;
private double cost; private double cost;
private boolean isQuickAggregateQuery, isDistinctQuery; private boolean isQuickAggregateQuery, isDistinctQuery;
private boolean isPrepared, checkInit; private boolean isPrepared, checkInit;
...@@ -492,6 +492,9 @@ public class Select extends Query { ...@@ -492,6 +492,9 @@ public class Select extends Query {
Expression expr = expressions.get(i); Expression expr = expressions.get(i);
row[i] = expr.getValue(session); row[i] = expr.getValue(session);
} }
if (isForUpdateMvcc) {
topTableFilter.lockRow();
}
result.addRow(row); result.addRow(row);
rowNumber++; rowNumber++;
if ((sort == null || sortUsingIndex) && limitRows != 0 && result.getRowCount() >= limitRows) { if ((sort == null || sortUsingIndex) && limitRows != 0 && result.getRowCount() >= limitRows) {
...@@ -539,7 +542,8 @@ public class Select extends Query { ...@@ -539,7 +542,8 @@ public class Select extends Query {
} }
topTableFilter.startQuery(session); topTableFilter.startQuery(session);
topTableFilter.reset(); topTableFilter.reset();
topTableFilter.lock(session, isForUpdate, isForUpdate); boolean exclusive = isForUpdate && !isForUpdateMvcc;
topTableFilter.lock(session, exclusive, exclusive);
if (isQuickAggregateQuery) { if (isQuickAggregateQuery) {
queryQuick(columnCount, result); queryQuick(columnCount, result);
} else if (isGroupQuery) { } else if (isGroupQuery) {
...@@ -962,6 +966,9 @@ public class Select extends Query { ...@@ -962,6 +966,9 @@ public class Select extends Query {
public void setForUpdate(boolean b) { public void setForUpdate(boolean b) {
this.isForUpdate = b; this.isForUpdate = b;
if (SysProperties.SELECT_FOR_UPDATE_MVCC && session.getDatabase().isMultiVersion()) {
isForUpdateMvcc = b;
}
} }
public void mapColumns(ColumnResolver resolver, int level) { public void mapColumns(ColumnResolver resolver, int level) {
......
...@@ -526,6 +526,12 @@ public class SysProperties { ...@@ -526,6 +526,12 @@ public class SysProperties {
*/ */
public static boolean runFinalize = getBooleanSetting("h2.runFinalize", true); public static boolean runFinalize = getBooleanSetting("h2.runFinalize", true);
/**
* System property <code>h2.selectForUpdateMvcc</code> (default: false).<br />
* If set, SELECT .. FOR UPDATE queries lock the rows when using MVCC.
*/
public static final boolean SELECT_FOR_UPDATE_MVCC = getBooleanSetting("h2.selectForUpdateMvcc", false);
/** /**
* System property <code>h2.serverCachedObjects</code> (default: 64).<br /> * System property <code>h2.serverCachedObjects</code> (default: 64).<br />
* TCP Server: number of cached objects per session. * TCP Server: number of cached objects per session.
......
...@@ -385,7 +385,9 @@ public class RegularTable extends TableBase { ...@@ -385,7 +385,9 @@ public class RegularTable extends TableBase {
} }
if (!force && database.isMultiVersion()) { if (!force && database.isMultiVersion()) {
// MVCC: update, delete, and insert use a shared lock. // MVCC: update, delete, and insert use a shared lock.
// Select doesn't lock // Select doesn't lock except when using FOR UPDATE and
// the system property h2.selectForUpdateMvcc
// is not enabled
if (exclusive) { if (exclusive) {
exclusive = false; exclusive = false;
} else { } else {
......
...@@ -718,4 +718,15 @@ public class TableFilter implements ColumnResolver { ...@@ -718,4 +718,15 @@ public class TableFilter implements ColumnResolver {
return false; return false;
} }
public void lockRow() {
if (state == FOUND) {
Row row = get();
table.removeRow(session, row);
table.addRow(session, row);
if (join != null) {
join.lockRow();
}
}
}
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论