package clusterj; // Main.java /* SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL'; CREATE SCHEMA IF NOT EXISTS `clusterj` DEFAULT CHARACTER SET latin1 COLLATE latin1_bin ; -- ----------------------------------------------------- -- Table `clusterj`.`example` -- ----------------------------------------------------- CREATE TABLE IF NOT EXISTS `clusterj`.`example` ( `number` BIGINT UNSIGNED NOT NULL , PRIMARY KEY (`number`) , UNIQUE INDEX `number_UNIQUE` USING HASH (`number` ASC) ) ENGINE = ndbcluster; SET SQL_MODE=@OLD_SQL_MODE; SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS; */ // Set java.library.path variable to point to the directory containing the Cluster ndbclient library. // -Djava.library.path=C:\Work\Programming\MySQL\MySQL-Cluster\mysql-cluster-gpl-7.1.3-win32\lib import java.util.Properties; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import com.mysql.clusterj.ClusterJHelper; import com.mysql.clusterj.Session; import com.mysql.clusterj.SessionFactory; public class Main { public static void main(String[] args) { /* * MySQL Cluster generic Linux and Windows 7.1.3 * * Session factory in a different thread than sessions crashes JVM. * * If SessionFactory is initialized in a different thread than where * sessions are created, session.newInstance call will crash JVM. This * happens on Windows and Linux. In Windows the crash seems to be coming * from DomainFieldHandlerImpl and from line table.getColumn(columnName);. * * Workaround is to insert a dummy row (most likely any db access works) * from same thread where the SessionFactory is created. After this the * session seem to be working from other thread. */ ExecutorService pool = Executors.newFixedThreadPool(2); // 1. Manager created in main thread, Manager manager = new Manager(); //insert(1); // 2. Remove the comment to get this work. // 3. Inserting a row from different thread. pool.submit(new Insert(2)); } private static void insert(long number) { Session session = Manager.getSessionFactory().getSession(); IEntity entity = session.newInstance(IEntity.class); entity.setNumber(number); session.currentTransaction().begin(); session.persist(entity); session.currentTransaction().commit(); return; } } class Manager { static SessionFactory sessionfactory; Manager() { createClusterJSession(); return; } private void createClusterJSession() { Properties properties = new Properties(); properties.put("com.mysql.clusterj.connectstring", "localhost:1186"); properties.put("com.mysql.clusterj.database", "clusterj"); sessionfactory = ClusterJHelper.getSessionFactory(properties); return; } public static SessionFactory getSessionFactory() { return sessionfactory; } } class Insert implements Runnable { SessionFactory sessionfactory; long number; Insert(long number) { this.number = number; return; } private void insert(long number) { Session session = Manager.getSessionFactory().getSession(); IEntity entity = session.newInstance(IEntity.class); // Crash from here. entity.setNumber(number); session.currentTransaction().begin(); session.persist(entity); session.currentTransaction().commit(); return; } @Override public void run() { insert(this.number); } }