/*
* Copyright 2004-2011 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.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.h2.constant.ErrorCode;
import org.h2.test.TestBase;
import org.h2.util.Task;
/**
* Row level locking tests.
*/
public class TestRowLocks extends TestBase {
/**
* The statements used in this test.
*/
Statement s1, s2;
private Connection c1, c2;
/**
* Run just this test.
*
* @param a ignored
*/
public static void main(String... a) throws Exception {
TestBase.createCaller().init().test();
}
public void test() throws Exception {
testSetMode();
testCases();
deleteDb("rowLocks");
}
private void testSetMode() throws SQLException {
deleteDb("rowLocks");
c1 = getConnection("rowLocks");
Statement stat = c1.createStatement();
stat.execute("SET LOCK_MODE 2");
ResultSet rs = stat.executeQuery("call lock_mode()");
rs.next();
assertEquals("2", rs.getString(1));
c1.close();
}
private void testCases() throws Exception {
deleteDb("rowLocks");
c1 = getConnection("rowLocks;MVCC=TRUE");
s1 = c1.createStatement();
s1.execute("SET LOCK_TIMEOUT 10000");
s1.execute("CREATE TABLE TEST AS SELECT X ID, 'Hello' NAME FROM SYSTEM_RANGE(1, 3)");
c1.commit();
c1.setAutoCommit(false);
s1.execute("UPDATE TEST SET NAME='Hallo' WHERE ID=1");
c2 = getConnection("rowLocks");
c2.setAutoCommit(false);
s2 = c2.createStatement();
assertEquals("Hallo", getSingleValue(s1, "SELECT NAME FROM TEST WHERE ID=1"));
assertEquals("Hello", getSingleValue(s2, "SELECT NAME FROM TEST WHERE ID=1"));
s2.execute("UPDATE TEST SET NAME='Hallo' WHERE ID=2");
assertThrows(ErrorCode.LOCK_TIMEOUT_1, s2).
executeUpdate("UPDATE TEST SET NAME='Hi' WHERE ID=1");
c1.commit();
c2.commit();
assertEquals("Hallo", getSingleValue(s1, "SELECT NAME FROM TEST WHERE ID=1"));
assertEquals("Hallo", getSingleValue(s2, "SELECT NAME FROM TEST WHERE ID=1"));
s2.execute("UPDATE TEST SET NAME='H1' WHERE ID=1");
Task task = new Task() {
public void call() throws SQLException {
s1.execute("UPDATE TEST SET NAME='H2' WHERE ID=1");
}
};
task.execute();
Thread.sleep(100);
c2.commit();
task.get();
c1.commit();
assertEquals("H2", getSingleValue(s1, "SELECT NAME FROM TEST WHERE ID=1"));
assertEquals("H2", getSingleValue(s2, "SELECT NAME FROM TEST WHERE ID=1"));
c1.close();
c2.close();
}
private static String getSingleValue(Statement stat, String sql) throws SQLException {
ResultSet rs = stat.executeQuery(sql);
return rs.next() ? rs.getString(1) : null;
}
}