Hi

OK, so it turns out my original idea was a bad one.
Because of the way the locking works, it is not possible to display that information in the sessions table.

However, using JMX works. The attached patch correctly display ongoing transactions using the H2 JMX facility.
See the unit-test in the unit-test for how it works.

Regards, Noel.

On 2012-02-27 12:18, IntensiveH2 wrote:
Any news regarding my issue?

The last status was:
- command compact works but closes all current connection
- I tried "TRANSACTION_TIMEOUT" = 33554432 but I have issue.
- I tried code with TRANSACTION_START but WHERE TRANSACTION_START IS
NOT NULL returns nothing.

On 23 fév, 10:56, IntensiveH2<[email protected]>  wrote:
Hi,

I tested the compact command.
I have no issue regarding "corruption" but I need time to perform
additional validations.
But "compact command" closed all opened connection and if you have a
"pool" of connection, it's a problem
The error message is:
org.h2.jdbc.JdbcSQLException: Database is already closed (to disable
automatic closing at VM shutdown, add ";DB_CLOSE_ON_EXIT=FALSE" to the
db URL) [90121-164]

Thierry.

On 15 fév, 13:13, Noel Grandin<[email protected]>  wrote:







Hi
I had a quick bash at implementing this by taking an exclusive lock on
the DB and re-using the existing compacting code.
So I added a
   COMPACT
command.
But the unit test I added indicates that I'm corrupting the database
somehow.
Patch attached - Thomas, perhaps you have an idea?
Regards, Noel.
On 2012-02-15 11:51, IntensiveH2 wrote:
Thanks for the quick answer but currently it's not possible to reboot
my application on a regular basis because my application must ensure
scheduling, failover, HA ....
and it's not possible to stop it.
I really need to have a solution at runtime without restarting my
application.
Thanks.
On 15 f�v, 10:40, Noel Grandin<[email protected]>    wrote:
Not sure what Thomas' plans are,
but what I can suggest is that you set this setting to a nice large number
-Dh2.maxCompactTime=60000
And reboot your application on a regular basis.
See herehttp://www.h2database.com/html/grammar.html#shutdown
which sets the maximum time to compact the database on shutdown (in
milliseconds).
On 2012-02-15 11:05, IntensiveH2 wrote:
Hi,
I use H2 in a commercial product and I have an issue regarding the
size of the DB (with a customer).
Currently the DB size is 12 GB and after a shutdown compact/restart
the new size is 800 MB
When you start connection on DB (12 GB) it took around 70 minutes to
start (on solaris) before to shutdow it with the compact option.
This is not acceptable (from customer comment).
NOTE: current version used of h2 are 1.3.159, 1.3.161 and 1.3.163 (the
result is the same for all version)
Do you have planned (urgently) to defragment/compact at runtime
(similar to SHUTDOWN COMPACT) in a background thread?
Do you have another solution to avoid this issue (long startup and
compact at runtime)?
Best regards.
Thierry.
  online-compact.diff
11KAfficherTélécharger

--
You received this message because you are subscribed to the Google Groups "H2 
Database" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/h2-database?hl=en.

Index: src/main/org/h2/engine/Session.java
===================================================================
--- src/main/org/h2/engine/Session.java (revision 4123)
+++ src/main/org/h2/engine/Session.java (working copy)
@@ -488,6 +488,7 @@
             unlinkLobMap = null;
         }
         unlockAll();
+        transactionStart = 0;
     }
 
     private void checkCommitRollback() {
@@ -516,6 +517,7 @@
             autoCommit = true;
             autoCommitAtTransactionEnd = false;
         }
+        transactionStart = 0;
     }
 
     /**
@@ -834,9 +836,6 @@
      * Wait for some time if this session is throttled (slowed down).
      */
     public void throttle() {
-        if (currentCommandStart == 0) {
-            currentCommandStart = System.currentTimeMillis();
-        }
         if (throttle == 0) {
             return;
         }
@@ -860,10 +859,14 @@
      */
     public void setCurrentCommand(Command command) {
         this.currentCommand = command;
-        if (queryTimeout > 0 && command != null) {
+        if (command != null) {
             long now = System.currentTimeMillis();
             currentCommandStart = now;
-            cancelAt = now + queryTimeout;
+            if (queryTimeout > 0) {
+                cancelAt = now + queryTimeout;
+            }
+        } else {
+            currentCommandStart = 0;
         }
     }
 
@@ -1054,6 +1057,7 @@
     public void begin() {
         autoCommitAtTransactionEnd = true;
         autoCommit = false;
+        transactionStart = System.currentTimeMillis();
     }
 
     public long getSessionStart() {
@@ -1061,9 +1065,6 @@
     }
 
     public long getTransactionStart() {
-        if (transactionStart == 0) {
-            transactionStart = System.currentTimeMillis();
-        }
         return transactionStart;
     }
 
Index: src/main/org/h2/jmx/DatabaseInfo.java
===================================================================
--- src/main/org/h2/jmx/DatabaseInfo.java       (revision 4123)
+++ src/main/org/h2/jmx/DatabaseInfo.java       (working copy)
@@ -175,14 +175,17 @@
         StringBuilder buff = new StringBuilder();
         for (Session session : database.getSessions(false)) {
             buff.append("session id: ").append(session.getId());
-            buff.append(" user: 
").append(session.getUser().getName()).append('\n');
-            buff.append("connected: ").append(new 
Timestamp(session.getSessionStart())).append('\n');
+            buff.append("\tuser: 
").append(session.getUser().getName()).append('\n');
+            buff.append("\tconnected: ").append(new 
Timestamp(session.getSessionStart())).append('\n');
+            if (session.getTransactionStart() != 0) {
+                buff.append("\ttransactionStart: ").append(new 
Timestamp(session.getTransactionStart())).append('\n');
+            }
             Command command = session.getCurrentCommand();
             if (command != null) {
-                buff.append("statement: 
").append(session.getCurrentCommand()).append('\n');
+                buff.append("\tstatement: 
").append(session.getCurrentCommand()).append('\n');
                 long commandStart = session.getCurrentCommandStart();
                 if (commandStart != 0) {
-                    buff.append("started: ").append(new 
Timestamp(commandStart)).append('\n');
+                    buff.append("\tstarted: ").append(new 
Timestamp(commandStart)).append('\n');
                 }
             }
             Table[] t = session.getLocks();
Index: src/test/org/h2/test/unit/TestJmx.java
===================================================================
--- src/test/org/h2/test/unit/TestJmx.java      (revision 4123)
+++ src/test/org/h2/test/unit/TestJmx.java      (working copy)
@@ -8,10 +8,14 @@
 
 import java.lang.management.ManagementFactory;
 import java.sql.Connection;
+import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.HashMap;
 import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 import javax.management.Attribute;
+import javax.management.JMException;
 import javax.management.MBeanAttributeInfo;
 import javax.management.MBeanInfo;
 import javax.management.MBeanOperationInfo;
@@ -34,8 +38,12 @@
         TestBase.createCaller().init().test();
     }
 
-    @SuppressWarnings("unchecked")
     public void test() throws Exception {
+        testJMX();
+        testTransactionsInProgress();
+    }
+    
+    private void testJMX() throws Exception {
         HashMap<String, MBeanAttributeInfo> attrMap;
         HashMap<String, MBeanOperationInfo> opMap;
         String result;
@@ -104,8 +112,8 @@
         conn = getConnection("jmx;jmx=true");
 
         name = new ObjectName("org.h2:name=JMX,*");
-        Set set = mbeanServer.queryNames(name, null);
-        name = (ObjectName) set.iterator().next();
+        Set<ObjectName> set = mbeanServer.queryNames(name, null);
+        name = set.iterator().next();
 
         assertEquals("16384", mbeanServer.getAttribute(name, 
"CacheSizeMax").toString());
         mbeanServer.setAttribute(name, new Attribute("CacheSizeMax", 1));
@@ -122,4 +130,34 @@
 
     }
 
+    private void testTransactionsInProgress() throws SQLException, 
InterruptedException, JMException, NullPointerException {
+        MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
+        ObjectName name = new ObjectName("org.h2:name=JMX,path=mem_jmx");
+        
+        deleteDb("jmx");
+        final Connection conn = getConnection("mem:jmx;jmx=true");
+        final CountDownLatch latch = new CountDownLatch(1);
+        
+        new Thread("TestJmx,sleep") {
+            public void run() {
+                try {
+                    conn.setAutoCommit(false);
+                    Statement stat = conn.createStatement();
+                    stat.execute("CREATE ALIAS sleep FOR 
\"java.lang.Thread.sleep\"");
+                    stat.execute("begin");
+                    latch.countDown();
+                    stat.execute("call sleep(2000)");
+                } catch (SQLException ex) {}
+            }
+        }.start();
+
+        latch.await(2000, TimeUnit.MILLISECONDS);
+        Thread.sleep(200);
+        
+        String result = mbeanServer.invoke(name, "listSessions", null, 
null).toString();
+        assertTrue(result.indexOf("transactionStart:") >= 0);
+        assertTrue(result.indexOf("call sleep") >= 0);
+        
+        conn.close();
+    }
 }

Reply via email to