I am using h2 (1.4.199) as the basis of a "data-preparation"-tool, i.e. 
with a focus on creating/editing/dropping tables. I am aware that h2 
(mvstore) may not have been developed for such an application.

My problem: I run into an exception on multi-threaded table editing. The 
attached 72-line java program starts two threads that repeatedly 
create/edit/drop each of them one table. After a few cycles there seems to 
be a deadlock that seems to be resolved after 2000 ms, one of the two 
threads dies (in my code), the other continues. Here is a typical output on 
my computer (core-i5 with 8Gbyte).


Started two threads 'AAA' and 'BBB'

thread AAA required 2021 ms at step: 39

thread BBB stopped with exception at step: 37
    msg: Timeout trying to lock table "SYS"; SQL statement:
alter table BBB add column if not exists X BIGINT as -1L [50200-199]

thread: AAA finished OK


Is there anything I could change to prevent this error ?

regards, rafel

-- 
You received this message because you are subscribed to the Google Groups "H2 
Database" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/h2-database/df0fd8f0-a65a-4903-873f-ac445dc1fd7e%40googlegroups.com.
package test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.h2.tools.Server;

public class Test {

	static Connection connection;
	static ExecutorService threadPool = Executors.newCachedThreadPool();

	public static void main(String[] args) {

		try {

			// start h2
			String dbURL = "jdbc:h2:./testMVCC;MVCC=true;AUTO_SERVER=TRUE;ALIAS_COLUMN_NAME=TRUE";
			Server.createTcpServer().start();

			// create two threads
			for (String x : new String[] {"AAA", "BBB"}) {

				final String tName = x;
				threadPool.submit(new Runnable() {

					Connection connection = DriverManager.getConnection(dbURL);

					void execute(String sql) throws SQLException {
						connection.createStatement().execute(sql);
					}

					@Override
					public void run() {

						int step=0;

						try {

							// repeat three statements: create/edit/drop a table
							for (step=0; step<1000; step++) {
								
								Long start = System.currentTimeMillis();
								execute("create table if not exists " + tName + " as select 7");
								execute("alter table " + tName + " add column if not exists X BIGINT as -1L");
								execute("drop table if exists " + tName );
								Long time = System.currentTimeMillis() - start;
								if (time > 1000 ) {
									System.out.println("\nthread " + tName + " required " 
											+ (System.currentTimeMillis() - start)  + " ms at step: " + step);            	
								}
								
							}
							
							System.out.println("\nthread: " + tName + " finished OK");            																				

						} catch (Exception e) {
							System.out.println("\nthread " + tName + " stopped with exception at step: " + step 
									+ "\n\tmsg: " + e.getLocalizedMessage());
						}
					}
				});
			}
			System.out.println("Started two threads 'AAA' and 'BBB'");

		} catch (SQLException e) {
			System.out.println(e.getLocalizedMessage());
		}
	}
}

Reply via email to