Skip to content

fix(#572): autocommit default tx immediately after DDL execute - #584

Merged
satwareAG-ironMike merged 3 commits into
mainfrom
fix/issue-572-578-ddl-execute-commit
Aug 22, 2026
Merged

fix(#572): autocommit default tx immediately after DDL execute#584
satwareAG-ironMike merged 3 commits into
mainfrom
fix/issue-572-578-ddl-execute-commit

Conversation

@satwareAG-ironMike

Copy link
Copy Markdown

Closes #572. Successor of closed #581 (rebased onto post-#577 main).

Summary

DDL via fbird_prepare_ex($link, $sql, null) + execute ran on the default transaction but committed only at connection close (#294's free-path commit is gated on had_open_cursor, which DDL never has). Metadata locks lingered for the connection lifetime: DDL invisible to other connections, no-wait transactions blocked (#572 customer report).

Fix: commit the default tx right after successful DDL execution at execute_done in _php_fbird_exec. Mirrors #294 guards (default tr_list head only, non-persistent, not in MSHUTDOWN). Explicit transactions keep transactional-DDL semantics via the existing #540/#566 block. Same cursor-invalidation trade-off documented as #566.

TDD evidence

State Result
RED (fix stashed) Table unknown T572_DDL on second connection while first stays open
GREEN tests/ddl_default_tx_commit_001.phpt passes
Control re-run after restore GREEN again

Test mirrors the driver's exact call shape (fbird_prepare_ex(..., null) + FBIRD_CONNECT_FORCE_NEW second physical link).

Verification

Known limitation (honest)

Removes ONE lingering-lock source but does not by itself stop the #578 testSetIsolationLevelSerializable conflict. Other lock holders under investigation in #578 (engine-level fb_lock_print next).

DDL executed via fbird_prepare_ex($link,$sql,null)+fbird_execute() ran on
the DEFAULT transaction but only committed at connection close (#294's
free-path commit is gated on had_open_cursor, which DDL never has).
Metadata locks (RDB$RELATION_FIELDS et al.) therefore lingered for the
connection's lifetime, making the DDL invisible to other connections and
blocking their no-wait transactions.

Commit the default tx right after successful DDL execution at
execute_done. Mirrors #294 guards (default tr_list head only,
non-persistent links, not in MSHUTDOWN); explicit transactions keep
Firebird transactional DDL semantics via the #540/#566 block. Same
cursor-invalidation trade-off documented as #566.

TDD: tests/ddl_default_tx_commit_001.phpt (RED without fix - 'Table
unknown' on second connection while first stays open; GREEN with fix;
control re-verified after stash). Extension suite 414/0.

Note: this removes one lingering-lock source but does NOT by itself stop
the #578 testSetIsolationLevelSerializable lock conflict (still 1/2359 on
php84 full suite with this fix applied) - other lock holders remain under
investigation in #578.
Review finding: the #572 DDL autocommit ignored fbt_commit()'s return
value - on failure fbt_free() rolls back silently while execute returns
true (silent DDL loss), and the #570 retry path below became dead code.
Mirror the #570 immediate-query pattern: on failure close blocking
cursors (_php_fbird_close_tx_cursors, forward-declared) and retry once;
report via _php_fbird_error if the retry also fails. Drop the unused
duplicate ISC_STATUS buffer.

CHANGELOG: Unreleased entry for the #572 behavior change.

Verification: ddl_default_tx_commit_001 + bug570_ddl_autocommit PASS,
extension suite 415/0 (php85-fb3-dev).
@satwareAG-ironMike

Copy link
Copy Markdown
Author

Hardening pushed per review Finding 1+2 (9dd505d): commit return checked, #570-style cursor-close + single retry, error reported on final failure (no more silent rollback behind a true return). Unused buffer dropped. CHANGELOG Unreleased entry added. Verification: both target phpts PASS, extension suite 415/0.

The Stubs Sync Check requires --CLEAN-- sections in phpt files
containing DDL. Use the house clean.inc GC (drops leftover test DBs
via firebird.inc marker files).
@satwareAG-ironMike
satwareAG-ironMike merged commit 8a904a9 into main Aug 22, 2026
63 of 64 checks passed
@satwareAG-ironMike
satwareAG-ironMike deleted the fix/issue-572-578-ddl-execute-commit branch August 22, 2026 20:59
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.

DDL visibility race recurs on v13.2.7 / Firebird 3.0.14 (#570 fix incomplete?)

1 participant