PEAR is discontinued

This is a static archive preserving historical releases and metadata. No new packages or updates will be published. For updates to existing packages, or to publish new packages, please use Composer and Packagist.

Home » Database » DB » Bug #2666

Transaction problem with mysql "SELECT ... FOR UPDATE"

Details

Submitted2004-11-01 17:32 UTC
Fromvile at nativecomm dot net
Assigneddanielc
StatusBogus
PackageDB
PHP VersionIrrelevant
OSIrrelevant
Roadmaps(Not assigned)

Comments

[2004-11-01 17:32 UTC] vile at nativecomm dot net

Description:
------------
There is a problem with transactions with mysql (maybe also with other DB engines).
SELECT ... FOR UPDATE has to be treaten as manipulation query. Because it is not treaten like that , a simple transaction like:
BEGIN
SELECT ... FOR UPDATE
UPDATE
COMMIT
cannot been realized with PEAR::DB

Reproduce code:
---------------
//table voucher is an InnoDB table

$gdb->autoCommit(FALSE);
$sql = "SELECT id,credits FROM voucher WHERE status='ENABLED' and secret='$code' for update;"; if($row = $gdb->getRow($sql)) {
$gdb->query("UPDATE voucher SET status='USED', used=NOW() where id=".$row[0].";");
$gdb->commit();
return $row[1];
} else {
$gdb->commit();
return -1;
}

Expected result:
----------------
a safe transaction ;)

Actual result:
--------------
there is no transaction

[2004-11-03 09:21 UTC] vile at nativecomm dot net

Here is the table, but i think thats irrelevant. The table surely works safely with transactions.
I solved the problem for myself - i'v edited the PEAR:DB's mysql.php in the DB directory and change the function simpleQuery:

if (!$this->autocommit && $ismanip) {

with

if (!$this->autocommit) {

and it's work , but that is not a nice solution.
It will be better solution to change the DB::isManip to recognise the SELECT .. FOR UPDATE query as a manipulation query.

CREATE TABLE `voucher` (
`id` bigint(20) unsigned NOT NULL auto_increment,
`secret` varchar(32) NOT NULL default '',
`status` enum('ENABLED','USED','DISABLED') NOT NULL default 'ENABLED',
`serie` varchar(16) NOT NULL default '',
`credits` int(11) NOT NULL default '0',
`created` datetime NOT NULL default '0000-00-00 00:00:00',
`used` datetime NOT NULL default '0000-00-00 00:00:00',
`fk_user` int(11) NOT NULL default '0',
PRIMARY KEY (`id`),
UNIQUE KEY `secret` (`secret`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;