Hi Rafał,

a test case will probably not be necessary. Looks like the
DatabaseJournal does not save the returned revision_id along with the
record currently being created but rather as one of its instance
member variables and therefore incorrectly associates both records
with the same revision_id. The commit() call after having inserted
only the first of two records is another defect: apparently the
DatabaseJournal's lock is not truly reentrant. I will file a jira
issue for this.

Thanks for reporting this bug!
Dominique

On 3/28/07, Rafał Kwiecień <[EMAIL PROTECTED]> wrote:
Hi Dominique

Dnia środa, 28 marca 2007 09:46, Dominique Pfister napisał:
> Hi Rafał,
>
> judging from the fact that the revision id is incremented twice and
> then applied to two different records, I ask myself whether these
> records are appended from the *same* thread in the *same* instance.
Yes - the same thread and the same instance of DatabaseJournal

> When appending a record to the DatabaseJournal, the order of SQL calls
> is as follows:
>
> -- BEGIN TRANSACTION --
> UPDATE global_revision SET revision_id = revision_id + 1
> SELECT revision_id FROM global_revision
> INSERT INTO revision(revision_id, ...) VALUES (?,...)
> -- COMMIT --

I my case it looks like:

-- BEGIN TRANSACTION --
UPDATE global_revision SET revision_id = revision_id + 1
SELECT revision_id FROM global_revision
UPDATE global_revision SET revision_id = revision_id + 1
SELECT revision_id FROM global_revision
INSERT INTO revision(revision_id, ...) VALUES (?,...)
-- COMMIT --
INSERT INTO revision(revision_id, ...) VALUES (?,...)
-- COMMIT --

>
> The first call is supposed to lock the global_revision table, the
> second will fetch the new revision_id and the last one will append a
> record with that new revision_id. If two instances would get the same
> revision_id, something would be seriously strange with the database
> transaction isolation. Two different threads in the same instance
> block each other until one has actually finished appending the new
> record. Therefore, the only conceivable scenario are  reentrant
> updates made by the same thread.

After debugging I can say more about the problem. When transaction is
committed, there are methods prepare() and commit() called on
TransactionContext object. TransactionContext.resources contains five
objects: XAWorkspace, XAItemStateManager, XALockManager, XAVersionManager,
XAWorkspace. First TransactionContext.prepare() is called - and for each
resource prepare(). DatabaseJournal.doLock() is called twice (by
XAItemStateManager and XAVersionManager). When TransactionContext.commit() is
called, also method commit() for each resource is called. And
DatabaseJournal.append() is called twice (also by XAItemStateManager and
XAVersionManager).

>
> Can you reproduce your situation with a simple test case? This would
> definitely help...

Sorry, I don't have simple test case. You can download spring-modules package
and run jcr sample. If you add cluster configuration to jackrabbit-repo.xml,
you get error.


--
Rafał Kwiecień
ConSol* Consulting & Solutions Software Poland Sp. z o.o.
ul. Piastowska 44C, 30-070 Kraków
http://www.consol.pl/

Reply via email to