S
S
sir_genry2018-03-27 10:10:39
PHP
sir_genry, 2018-03-27 10:10:39

PHP PDO How to achieve synchronous COMMIT work?

Hello!
To clarify the essence of the issue, I will give the following case:
1. We execute a transaction in PHP script No. 1, which we complete with a commit
2. We send a message to RabbitMQ.
3. The script ends
4. At the same time, another process (script #2) listens to the queue and receives the message sent by script #1.
5. Script No. 2 searches for a record in the database. which Script #1 just created. And he doesn't find it!
6. We are waiting for some time, the record appears.
Conclusion: Commit works asynchronously.
Question: Is there a way to wait for the real end of the commit and only after that continue the script execution?
Using different isolation levels does not help

Answer the question

In order to leave comments, you need to log in

4 answer(s)
S
sir_genry, 2018-03-28
@sir_genry

If someone is interested, then I inform you that using PDOStatement::execute instead of PDO::commit solved the problem in my case.
On the example of the yii2 framework /
It was:

$transaction = \Yii::$app->db->beginTransaction();
try {
    ...
    $transaction->commit();
} catch (\Exception $exception) {
    $transaction->rollBack();
    throw $exception;
}

It became:
\Yii::$app->db->createCommand('BEGIN TRANSACTION')->execute();
try {
    ...
    \Yii::$app->db->createCommand('COMMIT TRANSACTION')->execute();
} catch (\Exception $exception) {
    \Yii::$app->db->createCommand('ROLLBACK TRANSACTION')->execute();
    throw $exception;
}

It's not entirely beautiful, of course, and I'm not completely sure that it works in all cases. But still better than artificial delay

M
Melkij, 2018-03-27
@melkij

For an application, the commit is synchronous. If you exited commit(), then the transaction has already been committed.
Check application code #2. Maybe you're already in a transaction and that's why you don't see the change. Maybe you are connecting to an asynchronous replica

K
Konstantin Malyarov, 2018-03-27
@Konstantin18ko

Between points 1 and 2, make a check.
1. We execute a transaction in PHP script No. 1, which we complete with a commit
2. Check if a record has been added, if yes, go to step 3, if not, repeat step 2 after 5 seconds.
3. We send a message to RabbitMQ.
...

P
profaller, 2018-03-29
@profaller

In the second script, you need to fix the snapshot timestamp, either through COMMIT, or you need to make a selection with a lock through SELECT ... LOCK IN SHARE MODE, so you get a fresh data selection.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question