<< Back to previous view

[QB-2006] h2 Engine blocks Quickbuild
Created: 02/Apr/14  Updated: 03/Apr/14

Status: Resolved
Project: QuickBuild
Component/s: None
Affects Version/s: 5.1.18
Fix Version/s: 5.1.19

Type: Bug Priority: Major
Reporter: AlSt Assigned To: Unassigned
Resolution: Fixed Votes: 0
Remaining Estimate: Unknown Time Spent: Unknown
Original Estimate: Unknown

File Attachments: PNG File qb_blocking.PNG     Text File threaddump.txt    

 Description   
Quickbuild gets blocked by h2 Engine and is not usable anymore. Seems there is a bug in the h2 version Quickbuild is using.

 Comments   
Comment by Robin Shen [ 02/Apr/14 09:46 AM ]
We always suggest to use external database for production usage as internal H2 database is not stable enough and is only for demonstration purpose.
Comment by AlSt [ 02/Apr/14 09:46 AM ]
If you need more information please contact me.
Comment by AlSt [ 02/Apr/14 09:49 AM ]
We are using mysql, so this happens anyway.
Comment by Robin Shen [ 02/Apr/14 09:53 AM ]
Can you please run jstack against QB JVM and attach the thread dump when this happens?
Comment by AlSt [ 02/Apr/14 10:04 AM ]
Thread dump uploaded.

It seems that openSession() has some kind of a timeout defined in the newest h2 version, but the used one. 1.5.159 does not have this.
Comment by Robin Shen [ 02/Apr/14 12:38 PM ]
Will this block forever?
Comment by AlSt [ 02/Apr/14 01:48 PM ]
After about 1 hour we restarted the server because nothing the UI did not respond anymore.

In the Engine code I discovered this for 1.3.167 (which is a bit newer as the used 1.3.159 which i call 1.5.159 in my previous comment by mistake):

 while (true) {
            session = openSession(ci, ifExists, cipher);
            if (session != null) {
                break;
            }
            // we found a database that is currently closing
            // wait a bit to avoid a busy loop (the method is synchronized)
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                // ignore
            }
 }

So if session always returns null (and it seems that's the case) It blocks the object forever as the method is synchronized.

In version 1.3.174:
for (int i = 0;; i++) {
            session = openSession(ci, ifExists, cipher);
            if (session != null) {
                break;
            }
            // we found a database that is currently closing
            // wait a bit to avoid a busy loop (the method is synchronized)
            if (i > 60 * 1000) {
                // retry at most 1 minute
                throw DbException.get(ErrorCode.DATABASE_ALREADY_OPEN_1, "Waited for database closing longer than 1 minute");
            }
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                // ignore
            }
        }
Generated at Thu May 16 22:34:36 UTC 2024 using JIRA 189.