Skip to content

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

Closed
satwareAG-ironMike wants to merge 1 commit into
fix/issue-576-conn-res-uaffrom
fix/issue-572-578-ddl-execute-commit
Closed

fix(#572): autocommit default tx immediately after DDL execute#581
satwareAG-ironMike wants to merge 1 commit into
fix/issue-576-conn-res-uaffrom
fix/issue-572-578-ddl-execute-commit

Conversation

@satwareAG-ironMike

Copy link
Copy Markdown

Stacked on #577 (base = its head branch; GitHub retargets to main when #577 merges). Closes #572.

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)

This removes ONE lingering-lock source but does not by itself stop the #578 testSetIsolationLevelSerializable conflict (still 1/2359). Other lock holders under investigation in #578 - runtime MON$ snapshot research 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.
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.

1 participant