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
{{ message }}
Repository navigation
Commit 42eb56c
Browse filesBrowse the repository at this point in the historyBrowse files
fix(jdbc): serialize statement close and execute (#89)
Closes#49. Part of #54.
## What changed
- `LibsqlStatement` state transitions (`execute`, `executeQuery`,
`close`, result-set installation and removal, generated keys,
`getResultSet`, `isClosed`, `closeOnCompletion`) now share one private
lock.
- `execute`/`executeQuery` perform the network call outside the lock,
re-check `closed` under the lock, and only attach the result set if
close has not won. If close won, the produced result set is closed and
not attached.
- `close()` closes the current result set and generated keys while
holding the lock, then marks the statement closed.
- `LibsqlPreparedStatement` reuses the same
`assignResultSet`/`executeResult` paths, so prepared statements get the
same guarantee.
- Added `LibsqlStatementConcurrencyTest` with a deterministic latch seam
(`beforeResultSetAssignment`) between the closed check and result-set
installation. The test starts close while execute is paused in the seam,
so the race does not depend on timing luck.
## Contract decision
This is a correctness fix, not an xerial parity change. #47 deliberately
keeps execute-after-close working; that remains true: the call still
executes and does not throw. The one observable tightening is that a
result set produced after the statement is already closed is returned
closed instead of open. This is required by #49's acceptance criterion
that a closed statement never holds an open result set after execute
returns, and it also covers the reproduction where close completes
before the next execute starts.
## Evidence
Failing before the fix (seam and tests present, locking absent):
```
./mvnw -pl libsql-jdbc -am -Dtest=LibsqlStatementConcurrencyTest -Dsurefire.failIfNoSpecifiedTests=false test
Tests run: 3, Failures: 3, Errors: 0, Skipped: 0
plainExecuteQueryDoesNotAttachAnOpenResultSetWhenCloseWinsTheRace
preparedExecuteQueryDoesNotAttachAnOpenResultSetWhenCloseWinsTheRace
executeQueryOnAClosedStatementReturnsAClosedResultSet
```
Passing after the fix:
```
./mvnw -pl libsql-jdbc -am test
Tests run: 165, Failures: 0, Errors: 0, Skipped: 0
BUILD SUCCESS
```
The concurrency test was also run five times in a row, all green.
`./mvnw spotless:apply` and `./mvnw spotless:check` pass.
## Deviations
None for the Hrana transport or sqld. The only intentional behavior
change beyond the race is closing a result set produced by an execute on
an already-closed statement, described under Contract decision.
0 commit comments