mirror of
https://github.com/sigmasternchen/php-doc-en
synced 2025-03-15 16:38:54 +00:00

git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@317502 c90b9560-bf6c-de11-be94-00142212c4b1
141 lines
5.5 KiB
XML
141 lines
5.5 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- $Revision$ -->
|
|
|
|
<chapter xml:id="pdo.transactions" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<title>Transactions and auto-commit</title>
|
|
<para>
|
|
Now that you're connected via PDO, you must understand how PDO
|
|
manages transactions before you start issuing queries. If you've never
|
|
encountered transactions before, they offer 4 major features: Atomicity,
|
|
Consistency, Isolation and Durability (ACID). In layman's terms, any work
|
|
carried out in a transaction, even if it is carried out in stages, is
|
|
guaranteed to be applied to the database safely, and without interference
|
|
from other connections, when it is committed. Transactional work can also
|
|
be automatically undone at your request (provided you haven't already
|
|
committed it), which makes error handling in your scripts easier.
|
|
</para>
|
|
<para>
|
|
Transactions are typically implemented by "saving-up" your batch of
|
|
changes to be applied all at once; this has the nice side effect of
|
|
drastically improving the efficiency of those updates. In other words,
|
|
transactions can make your scripts faster and potentially more robust
|
|
(you still need to use them correctly to reap that benefit).
|
|
</para>
|
|
<para>
|
|
Unfortunately, not every database supports transactions, so PDO needs to
|
|
run in what is known as "auto-commit" mode when you first open the
|
|
connection. Auto-commit mode means that every query that you run has its
|
|
own implicit transaction, if the database supports it, or no transaction
|
|
if the database doesn't support transactions. If you need a transaction,
|
|
you must use the <function>PDO::beginTransaction</function> method to
|
|
initiate one. If the underlying driver does not support transactions, a
|
|
PDOException will be thrown (regardless of your error handling settings:
|
|
this is always a serious error condition). Once you are in a transaction,
|
|
you may use <function>PDO::commit</function> or
|
|
<function>PDO::rollBack</function> to finish it, depending on the success
|
|
of the code you run during the transaction.
|
|
</para>
|
|
<warning>
|
|
<para>
|
|
PDO only checks for transaction capabilities on driver level. If certain
|
|
runtime conditions mean that transactions are unavailable,
|
|
<methodname>PDO::beginTransaction</methodname> will still return &true;
|
|
without error if the database server accepts the request to start a
|
|
transaction.
|
|
</para>
|
|
<para>
|
|
An example of this would be trying to use transactions on MyISAM tables on
|
|
a MySQL database.
|
|
</para>
|
|
</warning>
|
|
<para>
|
|
When the script ends or when a connection is about to be closed, if you
|
|
have an outstanding transaction, PDO will automatically roll it back.
|
|
This is a safety measure to help avoid inconsistency in the cases where
|
|
the script terminates unexpectedly--if you didn't explicitly commit the
|
|
transaction, then it is assumed that something went awry, so the rollback
|
|
is performed for the safety of your data.
|
|
</para>
|
|
<warning>
|
|
<para>
|
|
The automatic rollback only happens if you initiate the transaction via
|
|
<function>PDO::beginTransaction</function>. If you manually issue a
|
|
query that begins a transaction PDO has no way of knowing about it and
|
|
thus cannot roll it back if something bad happens.
|
|
</para>
|
|
</warning>
|
|
<para>
|
|
<example><title>Executing a batch in a transaction</title>
|
|
<para>
|
|
In the following sample, let's assume that we are creating a set of
|
|
entries for a new employee, who has been assigned an ID number of 23.
|
|
In addition to entering the basic data for that person, we also need to
|
|
record their salary. It's pretty simple to make two separate updates,
|
|
but by enclosing them within the
|
|
<function>PDO::beginTransaction</function> and
|
|
<function>PDO::commit</function> calls, we are guaranteeing that no one
|
|
else will be able to see those changes until they are complete. If
|
|
something goes wrong, the catch block rolls back all changes made
|
|
since the transaction was started, and then prints out an error
|
|
message.
|
|
</para>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
try {
|
|
$dbh = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2',
|
|
array(PDO::ATTR_PERSISTENT => true));
|
|
echo "Connected\n";
|
|
} catch (Exception $e) {
|
|
die("Unable to connect: " . $e->getMessage());
|
|
}
|
|
|
|
try {
|
|
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
|
|
|
$dbh->beginTransaction();
|
|
$dbh->exec("insert into staff (id, first, last) values (23, 'Joe', 'Bloggs')");
|
|
$dbh->exec("insert into salarychange (id, amount, changedate)
|
|
values (23, 50000, NOW())");
|
|
$dbh->commit();
|
|
|
|
} catch (Exception $e) {
|
|
$dbh->rollBack();
|
|
echo "Failed: " . $e->getMessage();
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
You're not limited to making updates in a transaction; you can also issue
|
|
complex queries to extract data, and possibly use that information to
|
|
build up more updates and queries; while the transaction is active, you
|
|
are guaranteed that no one else can make changes while you are in the
|
|
middle of your work. For further reading on transactions, refer to the
|
|
documentation provided by your database server.
|
|
</para>
|
|
</chapter>
|
|
|
|
<!-- Keep this comment at the end of the file
|
|
Local variables:
|
|
mode: sgml
|
|
sgml-omittag:t
|
|
sgml-shorttag:t
|
|
sgml-minimize-attributes:nil
|
|
sgml-always-quote-attributes:t
|
|
sgml-indent-step:1
|
|
sgml-indent-data:t
|
|
indent-tabs-mode:nil
|
|
sgml-parent-document:nil
|
|
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
|
|
sgml-exposed-tags:nil
|
|
sgml-local-catalogs:nil
|
|
sgml-local-ecat-files:nil
|
|
End:
|
|
vim600: syn=xml fen fdm=syntax fdl=2 si
|
|
vim: et tw=78 syn=sgml
|
|
vi: ts=1 sw=1
|
|
-->
|
|
|