Re: DB_DataObject and transactions
| From: | Laszlo Hermann | Date: | Mon, 20 Sep 2004 18:31:57 +0000 |
| Subject: | Re: DB_DataObject and transactions | ||
| References: | 1 2 | Groups: | php.pear.general |
| Request: | Send a blank email to pear-general+get-14569@lists.php.net to get a copy of this message | ||
Thank you for your answer, Alan. You're right, DO does not remake connections.
Hoping to contribute to this list, I'm gonna summarize the conclusion:
DB_DataObject and transactions work great. The following example is
tested and it works fine. If a query fails or the connection
disconnects (see commented line), $errors is greater than zero and you
can roll it back.
$errors = 0;
$person = DB_DataObject::factory('person');
$conn = & $person->getDatabaseConnection();
$conn->autocommit();
$mom = DB_DataObject::factory('mom');
$mom->name = 'Mary';
$mom_id = $mom->insert();
if (!$mom_id) $errors++;
//$conn->disconnect();
$person->name = 'Fred';
$person->mom_id = $mom_id;
$res = $person->insert();
if (!$res) $errors++;
//do some stuff, more queries
if ($errors == 0) $conn->commit();
else $conn->rollback();
Regards,
Laszlo Hermann
On Mon, 20 Sep 2004 17:36:25 +0800, Alan Knowles <alan@akbkhome.com> wrote:
> oh, if only it used exceptions ;)
>
> - try sending
> $do->query("BEGIN");
> $do->query("COMMIT");
> $do->query("ROLLBACK");
> - Query intercepts these and calls autocommit/rollback etc. for you.
>
> I dont think (Although I've never tested it)., that DO will actually try
> and remake the connection if it's failed.. - If the PEAR::DB Object
> exists, it will try and use it, if it fails (due to the database
> connection going down) It should just return an error.
>
> so you should be able to check for a false return, and a PEAR:Error in
> the _lastError property.
>
> although I'm not that running ROLLBACK on the failed connection would
> have much effect..
>
> Regards
> Alan
>
>
>
>
> Laszlo Hermann wrote:
> > Ok, this is gonna be long.
> >
> > The question is: is there a way to use transactions with DB_DataObject?
> >
> > Let's take a look at the following code:
> >
> > $person = DB_DataObject::factory('person');
> > $conn = & $person->getDatabaseConnection();
> > $conn->autocommit(false);
> >
> > $mom = DB_DataObject::factory('person');
> > $mom->name = 'Mary';
> > $momId = $mom->insert(); //query 1
> >
> > //this comment is BOOKMARK 1 (the database connection breaks right here)
> > //do some stuff, then:
> >
> > $person->momId = $momId;
> > $person->name = 'Fred';
> > $person->insert(); //query 2
> >
> > $conn->rollback();
> >
> > For an easier understanding I ommitted all the error checkings.
> >
> > Because DataObjects reuse existent connections, this works great if
> > the database connection does not die. But what if....what if at the
> > line BOOKMARK 1 the connection breaks? Then "query 1" is automatically
> > rolled back (because the connection breaks), then DataObject creates a
> > new connection, with 'autocommit' being enabled (by default). Then
> > "query 2" goes through this new connection, is _executed_, and the
> > last command ($conn->rollback()) has absolutely no effect. So query 1
> > is rolled back, but query 2 is executed.
> >
> > The problem is that I can't even get an error message telling me the
> > connection has broken and an new connection has been created and query
> > 2 goes through this new connection.
> >
> > An alternative to this problem is the one suggeted by Torsten Roehr,
> > on 2004-06-14 14:54:27:
> >
> >
> >>You can do this (simplified):
> >>
> >>$errors = 0;
> >>
> >>// start transaction
> >>$db->autocommit(false);
> >>
> >>// 1st query
> >>$result = $db->query($query1);
> >>if (DB::isError($result)) $errors++;
> >>
> >>// 2nd query
> >>$result = $db->query($query2);
> >>if (DB::isError($result)) $errors++;
> >>
> >>// and so on
> >>
> >>// rollback if errors occurred
> >>if ($errors) {
> >> $db->query('ROLLBACK');
> >>} else {
> >> $db->query('COMMIT');
> >>}
> >>
> >>$db->autocommit(true);
> >
> >
> > Perfect, now if the connection breaks between the two queries I can
> > catch the error. The disadvantage of this method is the lack of
> > DataObjects.
> >
> > We've got to the point: is there a way to use DB_DataObject in
> > transactions? Is there a way to check if a new connection has been
> > established? Or can I 'tell' DataObject not to establish new
> > connections? I mean instead of establishing a new connection, return
> > me an error.
> >
> > Laszlo Hermann.
>
>