I am using a db_transaction() for some data updates. I am using some EntityMetadataWrappers, modify some data, then save.

The thing is, the wrapper ->save() function doesn't have a parameter for $transaction like the entity controller does: entity_get_controller($entity_type)->save($entity, $transaction).

If I don't pass in a transaction, it will call db_transaction() when one already exists.

  • What will happen in this case during commit or rollback of the outer transaction?
  • If a new transaction is created, does this commit the one that already existed?
  • If a rollback of the outer one won't rollback the inner one, or if it messes up stuff when a new one is created, then is there a way to do it all in one transaction?

Note: I'm using MariaDB.


I finally found an explanation of what happens in this case in the Transactions documentation.

While we cannot declare functions "transactional" in PHP, we can emulate Java's nesting logic by using objects with constructors and destructors. A function simply calls "$transaction = db_transaction();" as its first (or nearly first) operation to make itself transactional. If one transactional function calls another, our transaction abstraction layer nests them by performing no transactional operations (as far as the database sees) within the inner nesting layers.

To start a new transaction, simply call $transaction = db_transaction(); in your own code. The transaction will remain open for as long as the variable $transaction remains in scope. When $transaction is destroyed, the transaction will be committed. If your transaction is nested inside of another then Drupal will track each transaction and only commit the outer-most transaction when the last transaction object goes out out of scope, that is, all relevant queries completed successfully.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.