/*
* 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.db;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.h2.test.TestBase;
/**
* Tests the meta data tables information_schema.locks and sessions.
*/
public class TestSessionsLocks extends TestBase {
/**
* Run just this test.
*
* @param a ignored
*/
public static void main(String... a) throws Exception {
TestBase.createCaller().init().test();
}
public void test() throws Exception {
if (config.mvcc) {
return;
}
testCancelStatement();
testLocks();
deleteDb("sessionsLocks");
}
private void testLocks() throws SQLException {
deleteDb("sessionsLocks");
Connection conn = getConnection("sessionsLocks;MULTI_THREADED=1");
Statement stat = conn.createStatement();
ResultSet rs;
rs = stat.executeQuery("select * from information_schema.locks order by session_id");
assertFalse(rs.next());
Connection conn2 = getConnection("sessionsLocks");
Statement stat2 = conn2.createStatement();
stat2.execute("create table test(id int primary key, name varchar)");
conn2.setAutoCommit(false);
stat2.execute("insert into test values(1, 'Hello')");
rs = stat.executeQuery("select * from information_schema.locks order by session_id");
rs.next();
assertEquals("PUBLIC", rs.getString("TABLE_SCHEMA"));
assertEquals("TEST", rs.getString("TABLE_NAME"));
rs.getString("SESSION_ID");
if (config.mvcc) {
assertEquals("READ", rs.getString("LOCK_TYPE"));
} else {
assertEquals("WRITE", rs.getString("LOCK_TYPE"));
}
assertFalse(rs.next());
conn2.commit();
conn2.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
stat2.execute("SELECT * FROM TEST");
rs = stat.executeQuery("select * from information_schema.locks order by session_id");
if (!config.mvcc) {
rs.next();
assertEquals("PUBLIC", rs.getString("TABLE_SCHEMA"));
assertEquals("TEST", rs.getString("TABLE_NAME"));
rs.getString("SESSION_ID");
assertEquals("READ", rs.getString("LOCK_TYPE"));
}
assertFalse(rs.next());
conn2.commit();
rs = stat.executeQuery("select * from information_schema.locks order by session_id");
assertFalse(rs.next());
conn.close();
conn2.close();
}
private void testCancelStatement() throws Exception {
deleteDb("sessionsLocks");
Connection conn = getConnection("sessionsLocks;MULTI_THREADED=1");
Statement stat = conn.createStatement();
ResultSet rs;
rs = stat.executeQuery("select * from information_schema.sessions order by SESSION_START, ID");
rs.next();
int sessionId = rs.getInt("ID");
rs.getString("USER_NAME");
rs.getTimestamp("SESSION_START");
rs.getString("STATEMENT");
rs.getTimestamp("STATEMENT_START");
assertFalse(rs.next());
Connection conn2 = getConnection("sessionsLocks");
final Statement stat2 = conn2.createStatement();
rs = stat.executeQuery("select * from information_schema.sessions order by SESSION_START, ID");
assertTrue(rs.next());
assertEquals(sessionId, rs.getInt("ID"));
assertTrue(rs.next());
int otherId = rs.getInt("ID");
assertTrue(otherId != sessionId);
assertFalse(rs.next());
stat2.execute("set throttle 1");
final boolean[] done = { false };
Runnable runnable = new Runnable() {
public void run() {
try {
stat2.execute("select count(*) from system_range(1, 10000000) t1, system_range(1, 10000000) t2");
new Error("Unexpected success").printStackTrace();
} catch (SQLException e) {
done[0] = true;
}
}
};
new Thread(runnable).start();
while (true) {
Thread.sleep(100);
rs = stat.executeQuery("CALL CANCEL_SESSION(" + otherId + ")");
rs.next();
if (rs.getBoolean(1)) {
for (int i = 0; i < 20; i++) {
Thread.sleep(100);
if (done[0]) {
break;
}
}
assertTrue(done[0]);
break;
}
}
conn2.close();
conn.close();
}
}