ModeShape/modeshape — pull request #700 by rhauch (2013-02-15 20:36:37+00:00)
Title: MODE-1817 Corrected logic of concurrent removals

Added a relatively-simple test case that replicated the exact exception using my hypothesized scenario. The test creates separate threads to concurrently remove a specific node and (after synchronizing on a CyclicBarrier) save their changes. Thus, the transient state of each Session does not see the uncommitted transient state of the other Session, but both sessions are saved roughly the same time (in different threads so different transactions are used). But since both need to acquire the lock on the same parent node, only one session will proceed first to successfully remove the node. When the second session proceeds, it no accepts the fact that the node was already removed and proceeds accordingly.

(ACID transactions FTW!)

The fix was pretty simple: be aware that attempting to remove an entry in the cache may return null if the entry does not exist (i.e., was recently removed).