Drupal core cannot provide automatic transaction rollbacks for DDL (Data Definition Language) statements within hook_update_N because it must maintain compatibility with MySQL and MariaDB. In these databases, DDL statements trigger an implicit commit, which permanently commits any open transaction and prevents a rollback, regardless of whether the PHP execution fails later.
The Technical Constraint
While PostgreSQL supports transactional DDL (allowing a ROLLBACK to undo a CREATE TABLE or ALTER TABLE), Drupal's update system is designed for the lowest common denominator. Because MySQL cannot undo a schema change once the statement is executed, wrapping hook_update_N in a database transaction would provide a false sense of security for the majority of Drupal installations.
Declarative Schema Migrations
Adopting a declarative migration layer (similar to Doctrine Migrations) would not solve the underlying database limitation. Even with a declarative system, an "undo" mechanism would require the system to execute a compensating statement (e.g., running DROP COLUMN to undo an ADD COLUMN). This is inherently risky because:
- Data Loss: Dropping a column to "rollback" an update permanently deletes any data written to that column during the failed update.
- Complexity: Writing a perfect inverse for every possible schema change is error-prone and increases the codebase size.
Recommended Safeguards
Since automatic rollbacks are not viable at the core level, safety must be managed through execution patterns and environment controls:
- Idempotent Updates: Write updates that check for the existence of a field or table before attempting to create it. This allows a failed update to be re-run without triggering "table already exists" errors.
- Database Snapshots: The only guaranteed rollback mechanism for schema changes is a full database backup or VM snapshot taken immediately before running
update.php or drush updatedb.
- Staging Validation: Execute updates on a production-clone environment to identify failures before they hit the live database.
Execution Safeguards
To prevent partial schema changes from persisting, Drupal would need a "Dry Run" or "Schema Diff" mode. However, because DDL cannot be simulated without actually altering the table (or using complex shadow tables), this is not currently implemented in core. The current permission model (administer site configuration) controls who can start the process, but not the integrity of the process itself.
Diagnostic Detail Needed: Are you targeting a specific database backend (e.g., exclusively PostgreSQL), or must the solution remain cross-platform?