Improve documentation regarding deadlock in EventBus

This commit is contained in:
catbref 2020-12-02 13:16:18 +00:00
parent 54bb8ed817
commit 064e12a57b

View File

@ -22,18 +22,25 @@ public enum EventBus {
/**
* <b>WARNING:</b> before calling this method,
* make sure repository holds no locks, e.g. by calling
* make sure current thread's repository session
* holds no locks, e.g. by calling
* <tt>repository.saveChanges()</tt> or
* <tt>repository.discardChanges()</tt>.
* <p>
* This is because event listeners might open a new
* repository session which will deadlock HSQLDB
* if it tries to CHECKPOINT.
* <p>
* The HSQLDB deadlock occurs because the caller's
* repository session blocks the CHECKPOINT until
* their transaction is closed, yet event listeners
* new sessions are blocked until CHECKPOINT is
* completed, hence deadlock.
* The HSQLDB deadlock path is:
* <ul>
* <li>write-log <tt>blockchain.log</tt> has grown past CHECKPOINT threshold (50MB)</li>
* <li>alternatively, another thread has explicitly requested CHECKPOINT</li>
* <li>HSQLDB won't begin CHECKPOINT until all pending (SQL) transactions are committed or rolled back</li>
* <li>Same thread calls <tt>EventBus.INSTANCE.notify()</tt> <i>before</i> (SQL) transaction closed</li>
* <li>EventBus listener (same thread) requests a new repository session via <tt>RepositoryManager.getRepository()</tt></li>
* <li>New repository sessions are blocked pending completion of CHECKPOINT</li>
* <li>Caller is blocked so never has a chance to close (SQL) transaction - hence deadlock</li>
* </ul>
*/
public void notify(Event event) {
List<Listener> clonedListeners;