Writing to Tables in a failed Cake Transaction

The application I currently work on makes use of CakePHP database transactions. Database transactions allow you to easily roll back database changes. This works by adding database writes to a queue and not executing the queue until a commit statement is called. This gives a developer the opportunity to easily cancel writes if an error is encountered.

Without transactions you might have code like this:

Without transactions

In this example if anything fails during this order example we have to write code to delete the records that preceded the failure. This can get cumbersome when a process is dealing with a lot of records.

Making Use of Transactions

Using Cake 3 transactions

In our example above Cakes transaction system knows that if we exit on anything but true, such as an exception or false, that it should not commit the transaction. This makes life much easier for developers. But there is a problem.

A More Complex Example

Add a new connection for our logs

In this example we still have the same order processing code inside a transaction, but now we’ve introduced an external call to our partner who fulfills our make believe ordering system. Let’s imagine that method call does a series of API calls with that vendor to verify availability, pricing, and finally create the order. Lets also assume our API logic writes ever request/response to an api_log table to assist developers in debugging potential problems in our integration.

If this order failed during the API process we would lose all those logs. And if we lost all those logs we might not be able to debug our application. This is because those logs writes are still inside the transaction and transactions must return true before they are permanently written to the database.

We can work around this in Cake by adding a new database connection in our main app.php configuration file.

Create a New Connection to Write Outside Our Transaction

Using Our Logger Connection

Use our new logger connection in our logging method

There are a few other ways we could have done this. We could have instead created our connection at run-time without the need for a new connection in our config. We could have also chosen to tell our Table Registry to use our logger connection. It’s up to you and your application.

Putting this together we can now have all the benefits of transactions with all the benefits of excessive logging. For more information be sure to review the CakePHP docs on Accessing Connections and Database Configurations.