Skip to content

roll back a read acquire's open transaction when its SELECT fails#575

Merged
gaborbernat merged 2 commits into
tox-dev:mainfrom
dxbjavid:rw-read-acquire-rollback
Jul 3, 2026
Merged

roll back a read acquire's open transaction when its SELECT fails#575
gaborbernat merged 2 commits into
tox-dev:mainfrom
dxbjavid:rw-read-acquire-rollback

Conversation

@dxbjavid

Copy link
Copy Markdown
Contributor

The SQLite read/write lock takes a read lock in two steps: it issues a deferred BEGIN that grabs no database lock, and only the SELECT that follows actually takes the shared lock. The trouble is that if a writer takes the exclusive lock in the gap between those two statements, the SELECT fails with "database is locked" while the BEGIN's transaction is already open on the shared connection. The acquire path turns that error into a Timeout and releases its transaction mutex but never rolls the connection back, so it stays mid-transaction; from then on every acquire on that instance hits BEGIN again and dies with "cannot start a transaction within a transaction", wedging the lock for good (and for the async wrapper, the single worker thread it is pinned to). I came across it while reading how the release path was serialised in #563 and realised the acquire-failure path has no rollback at all. Rolling the connection back on failure, while the transaction mutex is still held, clears the half-open transaction and leaves a successful acquire untouched, so I kept the change inside _acquire.

@gaborbernat gaborbernat merged commit 1f6cde4 into tox-dev:main Jul 3, 2026
33 checks passed
@dxbjavid

dxbjavid commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review and merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants