The SAIL uses a ReentrantReadWriteLock to restrict the application to a single unisolated write connection. Since the ReentrantReadWriteLock is reentrant, it is possible to acquire more than one write connection from the same thread. This behavior is not supported and could lead to a degration of the ACID guarantee associated with the unisolated write connection.
The underlying concurrency constraint for the B+Tree is a single writer. Concurrent readers are allow and, when reading from a historical snapshot, concurrent readers never block. For the standalone database, this constraint is enforced by the UnisolatedReadWriteIndex class using a read/write lock. In the context described above (obtaining multiple unisolated writers for the sail), the UnisolatedReadWriteIndex should prevent data corruption. However, concurrent writer could degrade the ACID guarantee for the unisolated write connection. In effect, all writers would commit each time any writer commits.
As a workaround, do NOT request multiple unisolated write connections from within the same thread.
This problem could be fixed by saving a reference to the unisolated write connection while it is open and always returning the same reference when that connection is requested from a thread to which it has already been granted. Alternatively, we could use a counting semaphore to recognize when more than one request had been made and then block, but that would cause a deadlock when multiple requests for the unisolated write connection were made from the same thread. Rather than deadlocking, it would be preferrable to simply throw out an exception when this illegal pattern is detected.
Write a unit test which demonstrates this problem and then close the loophole.