amphp / postgres

Async Postgres client for PHP based on Amp.
MIT License
97 stars 20 forks source link

fix(transaction): transaction is never released #50

Closed azjezz closed 1 year ago

azjezz commented 2 years ago

Given the following example:

$config = Postgres\ConnectionConfig::fromString('host=127.0.0.1 port=32770 user=main password=main');
$link = Postgres\connect($config);
$trans = $link->beginTransaction();
$trans->query('DROP TABLE IF EXISTS test_users');
$trans->query('CREATE TABLE IF NOT EXISTS test_users (
        id SERIAL PRIMARY KEY,
        username VARCHAR(30) NOT NULL,
        email VARCHAR(1024) NOT NULL,
        password VARCHAR(1024) NOT NULL,
        status INT NOT NULL
    )');
$trans->commit();

$link->execute('INSERT INTO test_users (username, email, password, status) VALUES (?,?,?,?)', ['azjezz', 'azjezz@protonmail.com', '123456789', 1]);
$users = $link->execute('SELECT * FROM test_users');

var_dump(\iterator_to_array($users));

Prior to this change, i encounter the following error:

> php users.php
PHP Fatal error:  Uncaught Error: Event loop terminated without resuming the current suspension in /home/azjezz/Projects/neutomic/neu/vendor/revolt/event-loop/src/EventLoop/Internal/DriverSuspension.php:86
Stack trace:
#0 /home/azjezz/Projects/neutomic/neu/vendor/amphp/amp/src/Future.php(244): Revolt\EventLoop\Internal\DriverSuspension->suspend()
#1 /home/azjezz/Projects/neutomic/neu/vendor/amphp/postgres/src/Connection.php(75): Amp\Future->await()
#2 /home/azjezz/Projects/neutomic/neu/vendor/amphp/postgres/src/Connection.php(113): Amp\Postgres\Connection->awaitPending()
#3 /home/azjezz/Projects/neutomic/neu/example/users.php(25): Amp\Postgres\Connection->execute('INSERT INTO tes...', Array)
#4 {main}
  thrown in /home/azjezz/Projects/neutomic/neu/vendor/revolt/event-loop/src/EventLoop/Internal/DriverSuspension.php on line 86

Fatal error: Uncaught Error: Event loop terminated without resuming the current suspension in /home/azjezz/Projects/neutomic/neu/vendor/revolt/event-loop/src/EventLoop/Internal/DriverSuspension.php:86
Stack trace:
#0 /home/azjezz/Projects/neutomic/neu/vendor/amphp/amp/src/Future.php(244): Revolt\EventLoop\Internal\DriverSuspension->suspend()
#1 /home/azjezz/Projects/neutomic/neu/vendor/amphp/postgres/src/Connection.php(75): Amp\Future->await()
#2 /home/azjezz/Projects/neutomic/neu/vendor/amphp/postgres/src/Connection.php(113): Amp\Postgres\Connection->awaitPending()
#3 /home/azjezz/Projects/neutomic/neu/example/users.php(25): Amp\Postgres\Connection->execute('INSERT INTO tes...', Array)
#4 {main}
  thrown in /home/azjezz/Projects/neutomic/neu/vendor/revolt/event-loop/src/EventLoop/Internal/DriverSuspension.php on line 86

Now, this works as expected:

> php users.php
array(1) {
  [0]=>
  array(5) {
    ["id"]=>
    int(1)
    ["username"]=>
    string(6) "azjezz"
    ["email"]=>
    string(21) "azjezz@protonmail.com"
    ["password"]=>
    string(9) "123456789"
    ["status"]=>
    int(1)
  }
}

( note: the example above uses the v2 branch, but i'm assuming the issue is also present in v1 )

azjezz commented 2 years ago

Hm šŸ¤” commit doesn't decrement the refCount, is it supposed to?

azjezz commented 2 years ago

decrementing the refCount on commit/rollback also fixes this problem, so I'm not sure which one is the correct fix.

trowski commented 2 years ago

Yes, it does in v1, seems that was overlooked when upgrading to v2.

azjezz commented 2 years ago

tests are passing locally šŸŽ‰