提交 803781b5 authored 作者: Thomas Mueller's avatar Thomas Mueller

start to implement row level locks

上级 4908d970
......@@ -176,8 +176,10 @@ public abstract class Command implements CommandInterface {
session.commit(false);
} else if (session.getDatabase().getMultiThreaded()) {
Database db = session.getDatabase();
if (db != null && db.getLockMode() == Constants.LOCK_MODE_READ_COMMITTED) {
session.unlockReadLocks();
if (db != null) {
if (db.getLockMode() == Constants.LOCK_MODE_READ_COMMITTED) {
session.unlockReadLocks();
}
}
}
if (trace.isInfoEnabled()) {
......
......@@ -334,6 +334,13 @@ public class Constants {
*/
public static final int LOCK_MODE_READ_COMMITTED = 3;
/**
* The lock mode that means row level locks are used if possible.
* This lock mode is similar to read committed, but row level locks are
* used instead of table level locks.
*/
public static final int LOCK_MODE_ROW = 4;
/**
* The lock mode that means table level locking is used for reads and
* writes.
......
......@@ -1741,7 +1741,17 @@ public class Database implements DataHandler {
return maxMemoryUndo;
}
public void setLockMode(int lockMode) {
public void setLockMode(int lockMode) throws SQLException {
switch (lockMode) {
case Constants.LOCK_MODE_OFF:
case Constants.LOCK_MODE_READ_COMMITTED:
case Constants.LOCK_MODE_TABLE:
case Constants.LOCK_MODE_TABLE_GC:
case Constants.LOCK_MODE_ROW:
break;
default:
throw Message.getInvalidValueException("lock mode", "" + lockMode);
}
this.lockMode = lockMode;
}
......
......@@ -684,6 +684,7 @@ public class JdbcConnection extends TraceObject implements Connection {
transactionIsolationLevel = Connection.TRANSACTION_READ_UNCOMMITTED;
break;
case Constants.LOCK_MODE_READ_COMMITTED:
case Constants.LOCK_MODE_ROW:
transactionIsolationLevel = Connection.TRANSACTION_READ_COMMITTED;
break;
case Constants.LOCK_MODE_TABLE:
......
......@@ -377,13 +377,17 @@ public class TableData extends Table implements RecordReader {
}
} else {
if (lockExclusive == null) {
if (lockMode == Constants.LOCK_MODE_READ_COMMITTED && !database.getMultiThreaded() && !database.isMultiVersion()) {
// READ_COMMITTED read locks are acquired but they
// are released immediately
// when allowing only one thread, no read locks are
// required
return;
} else if (!lockShared.contains(session)) {
if (lockMode == Constants.LOCK_MODE_READ_COMMITTED || lockMode == Constants.LOCK_MODE_ROW) {
if (!database.getMultiThreaded() && !database.isMultiVersion()) {
// READ_COMMITTED read locks are acquired but they
// are released immediately
// when allowing only one thread, no read locks are
// required
// row level locks work like read committed
return;
}
}
if (!lockShared.contains(session)) {
traceLock(session, exclusive, "ok");
session.addLock(this);
lockShared.add(session);
......
......@@ -72,6 +72,7 @@ import org.h2.test.jdbcx.TestXASimple;
import org.h2.test.mvcc.TestMvcc1;
import org.h2.test.mvcc.TestMvcc2;
import org.h2.test.mvcc.TestMvcc3;
import org.h2.test.rowlock.TestRowLocks;
import org.h2.test.server.TestNestedLoop;
import org.h2.test.server.TestPgServer;
import org.h2.test.server.TestWeb;
......@@ -266,6 +267,8 @@ java org.h2.test.TestAll timer
/*
row level locking
run the performance tests as part of the unit test
switch to JDK 1.6 by default
......@@ -611,10 +614,11 @@ Roadmap:
new TestWeb().runTest(this);
new TestPgServer().runTest(this);
// mvcc
// mvcc & row level locking
new TestMvcc1().runTest(this);
new TestMvcc2().runTest(this);
new TestMvcc3().runTest(this);
new TestRowLocks().runTest(this);
// synth
new TestCrashAPI().runTest(this);
......
......@@ -74,7 +74,7 @@ public class TestCases extends TestBase {
sql = "delete from " + table;
}
stat.execute(sql);
stat.execute("script to 'test.sql'");
stat.execute("script to '" + baseDir + "/test.sql'");
}
conn.close();
}
......
......@@ -104,11 +104,11 @@ public class TestCsv extends TestBase {
list.add(new String[]{a, b});
prep.execute();
}
stat.execute("CALL CSVWRITE('test.csv', 'SELECT * FROM test', 'UTF-8', '|', '#')");
stat.execute("CALL CSVWRITE('" + baseDir + "/test.csv', 'SELECT * FROM test', 'UTF-8', '|', '#')");
Csv csv = Csv.getInstance();
csv.setFieldSeparatorRead('|');
csv.setFieldDelimiter('#');
ResultSet rs = csv.read("test.csv", null, "UTF-8");
ResultSet rs = csv.read(baseDir + "/test.csv", null, "UTF-8");
for (int i = 0; i < len; i++) {
assertTrue(rs.next());
String[] pair = (String[]) list.get(i);
......
/*
* Copyright 2004-2008 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.test.rowlock;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import org.h2.test.TestBase;
import org.h2.tools.DeleteDbFiles;
/**
* Row level locking tests.
*/
public class TestRowLocks extends TestBase {
private Connection c1, c2;
private Statement s1;
public void test() throws Exception {
testSetMode();
testCases();
}
private void testSetMode() throws Exception {
DeleteDbFiles.execute(null, "test", true);
Class.forName("org.h2.Driver");
c1 = DriverManager.getConnection("jdbc:h2:test", "sa", "sa");
Statement stat = c1.createStatement();
stat.execute("SET LOCK_MODE 4");
ResultSet rs = stat.executeQuery("call lock_mode()");
rs.next();
assertEquals("4", rs.getString(1));
c1.close();
}
private void testCases() throws Exception {
deleteDb("rowLocks");
c1 = getConnection("rowLocks");
s1 = c1.createStatement();
s1.execute("SET LOCK_MODE 4");
c2 = getConnection("rowLocks");
// s2 = c2.createStatement();
c1.setAutoCommit(false);
c2.setAutoCommit(false);
c1.close();
c2.close();
}
}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!--
Copyright 2004-2008 H2 Group. Multiple-Licensed under the H2 License, Version 1.0,,
and under the Eclipse Public License, Version 1.0
(http://h2database.com/html/license.html).
Initial Developer: H2 Group
-->
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head><meta http-equiv="Content-Type" content="text/html;charset=utf-8" /><title>
Javadoc package documentation
</title></head><body style="font: 9pt/130% Tahoma, Arial, Helvetica, sans-serif; font-weight: normal;">
Row level locking tests.
</body></html>
\ No newline at end of file
--- special grammar and test cases ---------------------------------------------------------------------------------------------
CREATE TABLE T(A NULL);
> exception
CREATE TABLE T(A INT);
> ok
ALTER TABLE T ALTER COLUMN A NULL;
> exception
DROP TABLE T;
> ok
CREATE ROLE TEST_A;
> ok
......
create table test (id varchar(36) as random_uuid() primary key);
insert into test() values();
delete from test where id = select id from test;
drop table test;
create table test (id varchar(36) as now() primary key);
insert into test() values();
delete from test where id = select id from test;
drop table test;
SELECT SOME(X>4) FROM SYSTEM_RANGE(1,6);
> TRUE;
SELECT EVERY(X>4) FROM SYSTEM_RANGE(1,6);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论