In the simple example of the teams table, if when the data is inserted for two teams, and the number of wins and losses for the two teams is accidentally swapped, an update would require both teams be modified, not just one. Suppose you are updating more than one table and the update statements in one table succeed and those in the other fail. For example, a classic example is that you take money out of a savings account in one table and put it in a checking account in another table. The deposit succeeds but the withdrawal fails. The tables are then in an inconsistent state. A transaction is a set of SQL statements that succeed or fail all as a unit. For example, INSERT, UPDATE, and DELETE statements may be executed as a group. If one fails, then none of the statements is executed.
By default, MySQL runs with autocommit mode enabled. DBI also runs with autocommit mode on by default. This means that as soon as you execute any statement that modifies a table, as long as no errors are returned, MySQL immediately commits the statement to the database, and any changes to the affected tables are made permanent.
To use transactions with MySql, autocommit mode must be disabled. We can do that in a Perl script when connecting to the database by setting the hash value of AutoCommit => 0 as shown in Example 17.43.
In the examples shown so far, when we connected to a database, the hash options available to the connect() method for error handling were used, PrintError and RaiseError. To use transactions, we need to turn off the AutoCommit attribute, turn RaiseErrors on, and optionally leave PrintError "on" or "off," "on" being the default.
1 my $dbh = DBI->connect( 'dbi:mysql:sample_db','root','quigley1', { PrintError => 0, RaiseError => 1, 2 AutoCommit => 0 } |
RaiseError tells DBI to die with the $DBI::errstr message if there are errors, and PrintError, by default turned on, tells DBI to send a warning with the $DBI::errstr and the program will continue to execute.
Commit means in a transaction that a set of statements will be executed and sent to the database as a group. If all of the statements are successful, the group is committed and the database is modified. If, however, there is an error in any one of the statements in the group, a rollback command is issued, which returns all the tables back to their previous state.
Transactions are often handled in Perl by using an eval block to trap errors, then using the commit() or rollback() methods to finish the transaction.
In the following example, a group of records will be inserted into a table. If an error occurs in the process of adding these entries, the entire process will be rolled back. The error could be because an entry already exists.