提交 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 {
public boolean isEverything(ExpressionVisitor visitor) {
switch(visitor.getType()) {
case ExpressionVisitor.DETERMINISTIC: {
if (isForUpdate) {
return false;
}
for (TableFilter f : filters) {
if (!f.getTable().isDeterministic()) {
return false;
......
......@@ -8,13 +8,13 @@ package org.h2.test.db;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Savepoint;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Random;
import org.h2.test.TestBase;
import org.h2.util.New;
......@@ -34,6 +34,7 @@ public class TestTransaction extends TestBase {
}
public void test() throws SQLException {
testForUpdate();
testRollback();
testSetTransaction();
testReferential();
......@@ -42,6 +43,30 @@ public class TestTransaction extends TestBase {
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 {
deleteDb("transaction");
Connection conn = getConnection("transaction");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论