提交 1548e103 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Fix concurrent deletion handling in SELECT FOR UPDATE

上级 5e137043
...@@ -35,6 +35,7 @@ import org.h2.result.LazyResult; ...@@ -35,6 +35,7 @@ import org.h2.result.LazyResult;
import org.h2.result.LocalResult; import org.h2.result.LocalResult;
import org.h2.result.ResultInterface; import org.h2.result.ResultInterface;
import org.h2.result.ResultTarget; import org.h2.result.ResultTarget;
import org.h2.result.Row;
import org.h2.result.SearchRow; import org.h2.result.SearchRow;
import org.h2.result.SortOrder; import org.h2.result.SortOrder;
import org.h2.table.Column; import org.h2.table.Column;
...@@ -429,7 +430,11 @@ public class Select extends Query { ...@@ -429,7 +430,11 @@ public class Select extends Query {
int count = filters.size(); int count = filters.size();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
TableFilter tableFilter = filters.get(i); TableFilter tableFilter = filters.get(i);
tableFilter.set(tableFilter.getTable().lockRow(session, tableFilter.get())); Row row = tableFilter.getTable().lockRow(session, tableFilter.get());
if (row == null) {
return false;
}
tableFilter.set(row);
} }
return isConditionMet(); return isConditionMet();
} }
......
...@@ -231,7 +231,6 @@ public class TestTransaction extends TestDb { ...@@ -231,7 +231,6 @@ public class TestTransaction extends TestDb {
Connection conn2 = getConnection("transaction"); Connection conn2 = getConnection("transaction");
Statement stat1 = conn1.createStatement(); Statement stat1 = conn1.createStatement();
stat1.execute("CREATE TABLE TEST (ID INT PRIMARY KEY, V INT)"); stat1.execute("CREATE TABLE TEST (ID INT PRIMARY KEY, V INT)");
stat1.execute("INSERT INTO TEST VALUES (1, 0)");
conn1.setAutoCommit(false); conn1.setAutoCommit(false);
conn2.createStatement().execute("SET LOCK_TIMEOUT 2000"); conn2.createStatement().execute("SET LOCK_TIMEOUT 2000");
if (config.mvStore) { if (config.mvStore) {
...@@ -250,15 +249,16 @@ public class TestTransaction extends TestDb { ...@@ -250,15 +249,16 @@ public class TestTransaction extends TestDb {
void testForUpdate2(Connection conn1, Statement stat1, Connection conn2, boolean forUpdate, void testForUpdate2(Connection conn1, Statement stat1, Connection conn2, boolean forUpdate,
boolean window) throws Exception { boolean window) throws Exception {
testForUpdate2(conn1, stat1, conn2, forUpdate, window, false); testForUpdate2(conn1, stat1, conn2, forUpdate, window, false, false);
testForUpdate2(conn1, stat1, conn2, forUpdate, window, true); testForUpdate2(conn1, stat1, conn2, forUpdate, window, false, true);
testForUpdate2(conn1, stat1, conn2, forUpdate, window, true, false);
} }
void testForUpdate2(Connection conn1, Statement stat1, final Connection conn2, boolean forUpdate, void testForUpdate2(Connection conn1, Statement stat1, final Connection conn2, boolean forUpdate,
boolean window, boolean excluded) throws Exception { boolean window, boolean deleted, boolean excluded) throws Exception {
stat1.execute("UPDATE TEST SET V = 1 WHERE ID = 1"); stat1.execute("MERGE INTO TEST KEY(ID) VALUES (1, 1)");
conn1.commit(); conn1.commit();
stat1.execute("UPDATE TEST SET V = 2 WHERE ID = 1"); stat1.execute(deleted ? "DELETE FROM TEST WHERE ID = 1" : "UPDATE TEST SET V = 2 WHERE ID = 1");
final int[] res = new int[1]; final int[] res = new int[1];
final Exception[] ex = new Exception[1]; final Exception[] ex = new Exception[1];
StringBuilder builder = new StringBuilder("SELECT V"); StringBuilder builder = new StringBuilder("SELECT V");
...@@ -293,7 +293,7 @@ public class TestTransaction extends TestDb { ...@@ -293,7 +293,7 @@ public class TestTransaction extends TestDb {
if (ex[0] != null) { if (ex[0] != null) {
throw ex[0]; throw ex[0];
} }
assertEquals(forUpdate ? excluded ? -1 : 2 : 1, res[0]); assertEquals(forUpdate ? (deleted || excluded) ? -1 : 2 : 1, res[0]);
} }
private void testRollback() throws SQLException { private void testRollback() throws SQLException {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论