提交 c3994b5d authored 作者: Thomas Mueller's avatar Thomas Mueller

If a FOR UPDATE query was executed twice (using a PreparedStatement), the table was not locked.

上级 e9cb54db
...@@ -1050,6 +1050,9 @@ public class Select extends Query { ...@@ -1050,6 +1050,9 @@ public class Select extends Query {
public boolean isEverything(ExpressionVisitor visitor) { public boolean isEverything(ExpressionVisitor visitor) {
switch(visitor.getType()) { switch(visitor.getType()) {
case ExpressionVisitor.DETERMINISTIC: { case ExpressionVisitor.DETERMINISTIC: {
if (isForUpdate) {
return false;
}
for (TableFilter f : filters) { for (TableFilter f : filters) {
if (!f.getTable().isDeterministic()) { if (!f.getTable().isDeterministic()) {
return false; return false;
......
...@@ -8,13 +8,13 @@ package org.h2.test.db; ...@@ -8,13 +8,13 @@ package org.h2.test.db;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DatabaseMetaData; import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Savepoint; import java.sql.Savepoint;
import java.sql.Statement; import java.sql.Statement;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Random; import java.util.Random;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.util.New; import org.h2.util.New;
...@@ -34,6 +34,7 @@ public class TestTransaction extends TestBase { ...@@ -34,6 +34,7 @@ public class TestTransaction extends TestBase {
} }
public void test() throws SQLException { public void test() throws SQLException {
testForUpdate();
testRollback(); testRollback();
testSetTransaction(); testSetTransaction();
testReferential(); testReferential();
...@@ -42,6 +43,30 @@ public class TestTransaction extends TestBase { ...@@ -42,6 +43,30 @@ public class TestTransaction extends TestBase {
deleteDb("transaction"); deleteDb("transaction");
} }
private void testForUpdate() throws SQLException {
deleteDb("transaction");
Connection conn = getConnection("transaction");
conn.setAutoCommit(false);
Statement stat = conn.createStatement();
stat.execute("create table test(id int primary key) as select 1");
conn.commit();
PreparedStatement prep = conn.prepareStatement("select * from test for update");
prep.execute();
// releases the lock
conn.commit();
prep.execute();
Connection conn2 = getConnection("transaction");
conn2.setAutoCommit(false);
try {
conn2.createStatement().execute("select * from test");
fail();
} catch (SQLException e) {
assertKnownException(e);
}
conn2.close();
conn.close();
}
private void testRollback() throws SQLException { private void testRollback() throws SQLException {
deleteDb("transaction"); deleteDb("transaction");
Connection conn = getConnection("transaction"); Connection conn = getConnection("transaction");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论