package my.test.mvstore;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;
import my.test.TestBase;
public class MVTableTest extends TestBase {
public static void main(String[] args) throws Exception {
new MVTableTest().start();
}
@Override
public void init() throws Exception {
prop.setProperty("MVCC", "true");
}
@Override
public void startInternal() throws Exception {
conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
stmt.executeUpdate("set MULTI_THREADED 1");
//stmt.executeUpdate("set MULTI_THREADED 0");
stmt.executeUpdate("set DEFAULT_LOCK_TIMEOUT 20000");
//conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
//create();
//test();
//stmt.executeUpdate("insert into MVTableTest(id, name, b) values(20, 'b1', true)");
testConcurrentUpdate();
//testConcurrentUpdate2();
//testTwoPhaseCommit();
}
public void testTwoPhaseCommit() throws Exception {
// JdbcDataSource ds = new JdbcDataSource();
// ds.setURL("jdbc:h2:tcp://localhost:9092/mydb");
// ds.setUser("sa");
// ds.setPassword("");
//
// XAConnection xacon1 = ds.getXAConnection();
// XAConnection xacon2 = ds.getXAConnection();
//
// XAResource resource1 = xacon1.getXAResource();
// //resource1.
// XAResource resource2 = xacon2.getXAResource();
stmt.executeUpdate("DROP TABLE IF EXISTS MVTableTest CASCADE");
sql = "CREATE TABLE IF NOT EXISTS MVTableTest(id int not null PRIMARY KEY, name varchar(500), b boolean) "
+ "ENGINE \"org.h2.mvstore.db.MVTableEngine\"";
stmt.executeUpdate(sql);
conn.setAutoCommit(false);
stmt.executeUpdate("insert into MVTableTest(id, name, b) values(10, 'a1', true)");
conn.commit();
stmt.executeUpdate("insert into MVTableTest(id, name, b) values(20, 'b1', true)");
stmt.execute("PREPARE COMMIT myxa");
stmt.execute("COMMIT TRANSACTION myxa");
sql = "select * from MVTableTest";
executeQuery();
}
public void create() throws Exception {
stmt.executeUpdate("DROP TABLE IF EXISTS MVTableTest CASCADE");
sql = "CREATE TABLE IF NOT EXISTS MVTableTest(id int not null PRIMARY KEY, name varchar(500), b boolean) "
+ "ENGINE \"org.h2.mvstore.db.MVTableEngine\"";
//sql = "CREATE TABLE IF NOT EXISTS MVTableTest(id int, name varchar(500), b boolean) ";
stmt.executeUpdate(sql);
}
public void test() throws Exception {
stmt.executeUpdate("DROP TABLE IF EXISTS MVTableTest CASCADE");
sql = "CREATE TABLE IF NOT EXISTS MVTableTest(id int not null, name varchar(500), b boolean) "
+ "ENGINE \"org.h2.mvstore.db.MVTableEngine\"";
//sql = "CREATE TABLE IF NOT EXISTS MVTableTest(id int, name varchar(500), b boolean) ";
stmt.executeUpdate(sql);
//也可建立与table.getName() + "_DATA"同名的索引,但是不会冲突,
//因为内部做了特殊处理,MVPrimaryIndex是不可见的,也不放入Meta表中
//stmt.executeUpdate("CREATE INDEX IF NOT EXISTS MVTableTest_DATA ON MVTableTest(name)");
//stmt.executeUpdate("DROP INDEX IF EXISTS MVTableTest_DATA");
//stmt.executeUpdate("CREATE INDEX IF NOT EXISTS MVTableTest_name ON MVTableTest(name desc)");
stmt.executeUpdate("CREATE UNIQUE INDEX IF NOT EXISTS MVTableTest_name ON MVTableTest(name desc)");
// stmt.executeUpdate("CREATE INDEX IF NOT EXISTS MVTableTest_name ON MVTableTest(name, b)");
// stmt.executeUpdate("CREATE INDEX IF NOT EXISTS MVTableTest_name ON MVTableTest(b, name)");
// stmt.executeUpdate("CREATE UNIQUE INDEX IF NOT EXISTS idx_MVTableTest_id ON MVTableTest(id)");
stmt.executeUpdate("CREATE PRIMARY KEY IF NOT EXISTS idx_MVTableTest_id ON MVTableTest(id)");
conn.setAutoCommit(false);
// stmt.executeUpdate("insert into MVTableTest(id, name, b) values(8, null, true)");
// stmt.executeUpdate("insert into MVTableTest(id, name, b) values(9, null, true)");
// stmt.executeUpdate("insert into MVTableTest(id, name, b) values(10, 'a1', true)");
// stmt.executeUpdate("insert into MVTableTest(id, name, b) values(20, 'b1', true)");
// stmt.executeUpdate("insert into MVTableTest(id, name, b) values(30, 'a2', false)");
// stmt.executeUpdate("insert into MVTableTest(id, name, b) values(40, 'b2', true)");
// stmt.executeUpdate("insert into MVTableTest(id, name, b) values(50, 'a3', false)");
//
// stmt.executeUpdate("insert into MVTableTest(id, name, b) values(60, 'b3', true)");
// stmt.executeUpdate("insert into MVTableTest(id, name, b) values(70, 'b3', true)");
// stmt.executeUpdate("insert into MVTableTest(id, name, b) values(-1, 'a1', true)");
//stmt.executeUpdate("insert into MVTableTest(id, name, b) values(-1, 'a1', true)");
//stmt.executeUpdate("insert into MVTableTest(id, name, b) values(10, 'a1', true)");
//for(int i=90;i<200;i++)
// stmt.executeUpdate("insert into MVTableTest(id, name, b) values("+i+", 'a1', true)");
stmt.executeUpdate("insert into MVTableTest(id, name, b) values(70, 'b4', true)");
//测试org.h2.mvstore.db.MVTable.addRow(Session, Row)中的rollbackToSavepoint
//同时测org.h2.mvstore.db.TransactionStore.rollbackTo(Transaction, long, long)
//MVPrimaryIndex对应的map会rollback
//idx_name对应的MVSecondaryIndex的map也会rollback
//stmt.executeUpdate("insert into MVTableTest(id, name, b) values(70, 'b3', true)");
//System.out.println(stmt.executeUpdate("delete from MVTableTest where id=70"));
conn.commit();
sql = "select * from MVTableTest where id=1";
sql = "select * from MVTableTest where id>1";
sql = "select * from MVTableTest where name>'a1' and name<'b3'";
sql = "select * from MVTableTest where name='a1'";
sql = "select * from MVTableTest where name>='b3' and name<'a1'";
sql = "select min(name) from MVTableTest";
sql = "select max(name) from MVTableTest";
sql = "select count(name) from MVTableTest"; //如果字段name的值是null,是不算在内的
//sql = "select count(id) from MVTableTest";
executeQuery();
}
// mysql> show variables where variable_name ='innodb_lock_wait_timeout';
// +--------------------------+-------+
// | Variable_name | Value |
// +--------------------------+-------+
// | innodb_lock_wait_timeout | 50 |
// +--------------------------+-------+
// Exception in thread "main" java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction
// at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1074)
// at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4096)
// at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4028)
// at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2490)
// at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2651)
// at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2728)
// at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1811)
void testConcurrentUpdate2() throws Exception {
Connection conn1 = DriverManager.getConnection(url, prop);
Connection conn2 = DriverManager.getConnection(url, prop);
Statement stmt1 = conn1.createStatement();
Statement stmt2 = conn2.createStatement();
try {
stmt.executeUpdate("delete from MVTableTest where id=80");
stmt.executeUpdate("insert into MVTableTest(id, name, b) values(80, 'b8', true)");
stmt.executeUpdate("delete from MVTableTest where id=80");
stmt.executeUpdate("insert into MVTableTest(id, name, b) values(80, 'b8', true)");
conn1.setAutoCommit(false);
conn2.setAutoCommit(false);
//stmt1.executeUpdate("update MVTableTest set name='a' where id=70");
stmt1.executeUpdate("delete from MVTableTest where id=80");
// ResultSet rs = stmt1.executeQuery("select * from MVTableTest where id=70");
// printResultSet(rs);
// rs.close();
//stmt2.executeUpdate("update MVTableTest set name='b3' where id=70");
stmt2.executeUpdate("delete from MVTableTest where id=80");
conn1.commit();
conn2.commit();
//sql = "select * from MVTableTest";
//executeQuery();
} finally {
stmt1.close();
conn1.close();
stmt2.close();
conn2.close();
}
}
void testConcurrentUpdate() throws Exception {
T1 t1 = new T1();
t1.prop = prop;
t1.url = url;
T2 t2 = new T2();
t2.prop = prop;
t2.url = url;
t1.start();
t2.start();
}
public static class T1 extends Thread {
Properties prop;
String url;
@Override
public void run() {
Connection conn1 = null;
Statement stmt1 = null;
try {
conn1 = DriverManager.getConnection(url, prop);
//conn1.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ); //不支持
//不能同时使用set MULTI_THREADED 1
//conn1.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
stmt1 = conn1.createStatement();
conn1.setAutoCommit(false);
stmt1.executeUpdate("insert into MVTableTest(id, name, b) values(30, 'b2', true)");
//stmt1.executeUpdate("insert into MVTableTest(id, name, b) values(30, 'b2', true)");
//stmt1.executeUpdate("update MVTableTest set name='b2' where id=20");
ResultSet rs = stmt1.executeQuery("select * from MVTableTest where id>=20");
printResultSet(rs);
rs.close();
rs = stmt1.executeQuery("select * from MVTableTest where id>=20");
printResultSet(rs);
rs.close();
stmt1.executeUpdate("delete from MVTableTest where id=30");
conn1.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
stmt1.close();
conn1.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void printResultSet(ResultSet rs) throws Exception {
int n = rs.getMetaData().getColumnCount();
while (rs.next()) {
for (int i = 1; i <= n; i++) {
System.out.print(rs.getString(i) + " ");
}
System.out.println();
//System.out.println(rs.getString(1) + " " + rs.getString(2) + " " + rs.getString(3) + " " + rs.getString(4));
}
}
}
public static class T2 extends Thread {
Properties prop;
String url;
@Override
public void run() {
Connection conn2 = null;
Statement stmt2 = null;
try {
conn2 = DriverManager.getConnection(url, prop);
stmt2 = conn2.createStatement();
conn2.setAutoCommit(false);
stmt2.executeUpdate("update MVTableTest set name='b8' where id=20");
conn2.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
stmt2.close();
conn2.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}