-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Transactions #28
Comments
👋 As transactions exist per database session it seems to me that the most obvious way to implement something like this is by adding the ability to lease a connection from the connection pool. When leasing a connection it's taken out of the pool of available connections and is only returned after the transaction has completed, guaranteeing that no other coroutine is adding queries to the transaction by mistake. The interface could look something like this: As all connections might be leased, the function should return a
Furthermore, we'd obviously also need a function to end the transaction and return the lease. |
Started working on something, see https://github.com/driftphp/reactphp-dbal/compare/master...bartvanhoutte:feature/transaction?expand=1. Small snippet demonstrating its behaviour: $connection1 = null;
$connection2 = null;
Loop::addTimer(10, static function () use (&$connection1, $pool) {
$pool->commitTransaction($connection1);
print 'releasing connection 1' . PHP_EOL;
});
Loop::addTimer(20, static function () use (&$connection2, $pool) {
$pool->commitTransaction($connection2);
print 'releasing connection 2' . PHP_EOL;
});
$connection1 = await($pool->startTransaction());
$connection2 = await($pool->startTransaction());
$connection3 = await($pool->queryBySQL('SELECT 1=1'));
print 'done' . PHP_EOL; A few pointers:
|
Why |
Seems good to me, BTW :) |
You're absolutely right. Currently the ConnectionPool takes the best connection so I assumed that was for a reason. I'll make the change. |
It looks like we'll have to maintain driver-specific syntax to start a transaction. DBAL currently calls I've added the above to my branch, do you want me to create a PR for easier reviewing? |
I think the PDO driver takes care of this ? I mean if the PDO constructor is set to use a mysql host , calling beginTransaction() will just do a START TRANSATION for you. I guess the interface src/Driver/Driver.php should be having a startTransaction() to be implemented by all Drift php database drivers. Which you did ! |
So for my understanding . In the "original" code what would happen if you would get a connection from the pool and do a "start transaction" ? I guess after this query has been executed the connection itself is set to available again ? What I can do, is testing your branch in our project using react php dbal . It will not use transactions, but at least we also test the existing non-transactions code still works. There should not be any breaking changes right ? I will let you guys know. |
I thought about this too, but PDO is only used in the child processes created in the driver and thus not available in
So there's a couple of issues here. The first issue is that using transactions in a For example: $connection = SingleConnection::createConnected(...$args);
Loop::futureTick(async(static function () use ($connection) {
await($connection->startTransaction());
await($connection->insert('foo', []));
await(\React\Promise\Timer\sleep(10));
await($connection->commitTransaction());
}));
Loop::addTimer(5, async(static function () use ($connection) {
await($connection->insert('foo', []));
})); In this case, the timer started in
Correct, the same issue described above can happen in a
Correct! Currently I'm testing the branch with transactions in a project of ours, so far so good. I can make a pull request to this project if it makes it easier to test @marinhekman. |
A couple of things to think about:
|
Thanks for explaining the leasing more in-depth. I do understand it better now, that a connection should not be reused in other coroutines, at least not for transactions. Let me look at the code more in-depth as well, e.g. wondering now if the leasing only takes place for transactions , or in general for instance. That's also "meets" your question above:
@mmoreram I would not mind to have a psr/log dependency introduced for logging, what do you think? |
@marinhekman monolog implements The question is which version of |
@mmoreram I guess you would like to support php7.4+ incl. php 8. If so, we cannot rely on php8 only, so we have to properly use psr/log version < 2 ? |
Since PHP 7.4 is officially end-of-life in three months I personally would prefer to drop support for PHP <= 8.0. New projects that are using PHP 8+ are presumably going to use |
Still alive here. I am gonna test this branch the next week or the one after. I will give an update after that |
@bartvanhoutte I tested our project on your branch , and did not encounter any issues. To be clear, we do not use any transactions , so using drift react without it still works . |
Hi, just to make sure, is transactions still in development or has it been integrated in the repo? |
@gabrielberthier Has been merged into master. |
Let's chat about how transactions can be implemented in the package.
The text was updated successfully, but these errors were encountered: