/* * TestSerializable.java * * Created on 22. prosinec 2002, 10:51 */ package cz.code.test; import java.sql.*; /** * * @author Administrator */ public class TestSerializable { String jdbc_url = "jdbc:postgresql://192.168.0.2:5432/web1"; String user = "web"; String pass = "web"; String table = "seq"; String name = "name"; String value = "seq"; String key = "GENID"; boolean thread1_ready = false; Object signal = new Object(); Thread thread1 = null; /** * @param args the command line arguments */ public static void main(String[] args) { try { new TestSerializable().run(); } catch (Exception e) { e.printStackTrace(); } } public void run() throws SQLException { try { Class driver = Class.forName("org.postgresql.Driver"); thread1 = new Thread1(); System.out.println("Main: starting threads"); thread1.start(); System.out.println("Main: getting connection..."); Connection c = DriverManager.getConnection(jdbc_url,user,pass); try { c.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); c.setAutoCommit(false); System.out.println("Main: waiting for other thread to get ready..."); // wait for other thread to get ready synchronized (signal) { while (!thread1_ready) { try { signal.wait(); } catch (InterruptedException e) { } } } System.out.println("Main: OK, performing locks..."); long v = 0; // perform select for update, which should lock records with update locks PreparedStatement s = c.prepareStatement("SELECT "+value+" FROM "+table+" WHERE "+name+" = ? FOR UPDATE"); try { s.setString(1, key); ResultSet rs = s.executeQuery(); try { rs.next(); v = rs.getLong(1); } finally { rs.close(); } } finally { s.close(); s = null; } System.out.println("Main: updating record..."); // update s = c.prepareStatement("UPDATE "+table+" SET "+value+" = ? WHERE "+name+" = ?"); try { s.setLong(1, v+1L); s.setString(2, key); s.executeUpdate(); } finally { s.close(); s = null; } // do not commit yet, hold the locks // signal other thread to try to get same data for update synchronized (signal) { thread1_ready = false; signal.notify(); } System.out.println("Main: Signalled other thread, sitting on locks for 10 seconds..."); try { Thread.sleep(10000); } catch (InterruptedException e) { } System.out.println("Main: committing transaction - second thread should unblock now"); c.commit(); } finally { c.close(); } } catch (Exception e) { System.out.println("Main: exception!"); e.printStackTrace(); } } public class Thread1 extends Thread { public void run() { try { System.out.println("Thread1: getting connection..."); Connection c1 = DriverManager.getConnection(jdbc_url,user,pass); c1.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); c1.setAutoCommit(false); System.out.println("Thread1: got connection..."); try { // notify main thread we'return ready... synchronized (signal) { thread1_ready = true; signal.notify(); // wait for signal while (thread1_ready) { try { signal.wait(); } catch (InterruptedException e) {} } } System.out.println("Thread1: now should block..."); long v = 0; PreparedStatement s = c1.prepareStatement("SELECT "+value+" FROM "+table+" WHERE "+name+" = ? FOR UPDATE"); try { s.setString(1, key); ResultSet rs = s.executeQuery(); try { rs.next(); v = rs.getLong(1); } finally { rs.close(); } } finally { s.close(); } System.out.println("Thread1: End of blocking!"); c1.commit(); } finally { c1.close(); } } catch (Exception e) { System.out.println("Thread1: exception!"); e.printStackTrace(); } } } }