You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
com.persistit.ExchangeLockTest.deadlock is flaky on CI. It fails at the second assertion, assertTrue(a._committed ^ b._committed). The timing assertion on the line before it passes.
The PR only touches maven-external-dependency-plugin, which has nothing to do with persistit.
[ERROR] com.persistit.ExchangeLockTest.deadlock -- Time elapsed: 0.122 s <<< FAILURE!
java.lang.AssertionError
at org.junit.Assert.assertTrue(Assert.java:53)
at com.persistit.ExchangeLockTest.deadlock(ExchangeLockTest.java:209)
Tests run: 592, Failures: 1, Errors: 0, Skipped: 5
Analysis
The test expects exactly one of the two lockers to commit. Both lockers can detect the deadlock at the same moment, and then both abort:
In cycle 0, a locks key 1 and b locks key 2. In cycle 1 the coordinator calls go(0), which does not wait. So a (asking for key 2) and b (asking for key 1) enter TransactionIndex.wwDependency concurrently.
wwDependency calls source.setDepends(target) and then isDeadlocked(source) (TransactionIndex.java ~L856). No victim is chosen.
If both threads set their dependency before either one checks, both see the cycle A→B→A and both return UNCOMMITTED. Both transactions then roll back, a._committed ^ b._committed is false, and the assertion fails.
Data stays correct in this case: the deadlock is resolved, just with two victims instead of one. This is the same mechanism as TransactionIndexTest.testDeadlockedWwDependency, fixed test-side in #256 ("deadlock may be detected by any participant").
Note: the test does not report the lockers' _exception, so the log does not show directly that both aborted. The mechanism above is inferred from the code.
Possible fixes
Test-side (as in Stabilize flaky TransactionIndexTest.testDeadlockedWwDependency #256): assert that at most one locker committed and that at least one got a deadlock/rollback. For example, assertFalse(a._committed && b._committed), plus a check on _exception. Also include _exception in the failure message for better diagnostics.
Product-side: pick a deterministic deadlock victim in wwDependency/isDeadlocked, for example abort only the transaction with the larger start timestamp. Exactly one participant would then abort, and the original assertion would hold. This is more invasive than the test-side fix.
Summary
com.persistit.ExchangeLockTest.deadlockis flaky on CI. It fails at the second assertion,assertTrue(a._committed ^ b._committed). The timing assertion on the line before it passes.Observed
build-maven (ubuntu-latest, 17). The other 8 build cells passed.maven-external-dependency-plugin, which has nothing to do withpersistit.Analysis
The test expects exactly one of the two lockers to commit. Both lockers can detect the deadlock at the same moment, and then both abort:
alocks key 1 andblocks key 2. In cycle 1 the coordinator callsgo(0), which does not wait. Soa(asking for key 2) andb(asking for key 1) enterTransactionIndex.wwDependencyconcurrently.wwDependencycallssource.setDepends(target)and thenisDeadlocked(source)(TransactionIndex.java~L856). No victim is chosen.UNCOMMITTED. Both transactions then roll back,a._committed ^ b._committedisfalse, and the assertion fails.Data stays correct in this case: the deadlock is resolved, just with two victims instead of one. This is the same mechanism as
TransactionIndexTest.testDeadlockedWwDependency, fixed test-side in #256 ("deadlock may be detected by any participant").Note: the test does not report the lockers'
_exception, so the log does not show directly that both aborted. The mechanism above is inferred from the code.Possible fixes
assertFalse(a._committed && b._committed), plus a check on_exception. Also include_exceptionin the failure message for better diagnostics.wwDependency/isDeadlocked, for example abort only the transaction with the larger start timestamp. Exactly one participant would then abort, and the original assertion would hold. This is more invasive than the test-side fix.