Using H2 database server how to notify changes to clients (JMS messaging)

后端 未结 1 959
庸人自扰
庸人自扰 2021-01-07 13:39

I am successfully using H2 database in AUTO_SERVER mode so that a database file is shared among a number of desktop clients on a network transparently. This way a server is

相关标签:
1条回答
  • 2021-01-07 14:08

    H2 does not implement JMS (in fact I don't know of a database that does). However, you could build a simple notify mechanism within H2, using a trigger and a user defined function, as follows. Please note this would require the multi-threaded mode in H2, which is not fully tested yet. Because of that, it might make sense to use a separate database for messaging than the database you use for your data.

    import java.sql.*;
    import java.util.concurrent.atomic.AtomicLong;
    import org.h2.tools.TriggerAdapter;
    
    public class TestSimpleDb {
    
        public static void main(String[] args) throws Exception {
            final String url = "jdbc:h2:mem:test;multi_threaded=true";
            Connection conn = DriverManager.getConnection(url);
            Statement stat = conn.createStatement();
            stat.execute("create alias wait_for_change for \"" + 
                    TestSimpleDb.class.getName() + 
                    ".waitForChange\"");
            stat.execute("create table test(id identity)");
            stat.execute("create trigger notifier " + 
                    "before insert, update, delete, rollback " +
                    "on test call \"" + 
                    TestSimpleDb.Notifier.class.getName() + "\"");
            new Thread() {
                public void run() {
                    try {
                        Connection conn = DriverManager.getConnection(url);
                        for (int i = 0; i < 10; i++) {
                            conn.createStatement().execute(
                                    "call wait_for_change(10000)");
                            System.out.println("Receiver: event received");
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }.start();
            Thread.sleep(500);
            for (int i = 0; i < 10; i++) {
                System.out.println("Sender: I change something...");
                stat.execute("insert into test values(null)");
                Thread.sleep(1000);
            }
            conn.close();
        }
    
        static AtomicLong modCount = new AtomicLong();
    
        public static void waitForChange(long maxWaitMillis) {
            synchronized (modCount) {
                try {
                    modCount.wait(maxWaitMillis);
                } catch (InterruptedException e) {
                    // ignore
                }
            }
        }
    
        public static class Notifier extends TriggerAdapter {
            public void fire(Connection conn, ResultSet oldRow, ResultSet newRow)
                    throws SQLException {
                modCount.incrementAndGet();
                synchronized (modCount) {
                    modCount.notifyAll();
                }
            }
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题