Skip to content
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

Transaction already in progress #2720

Closed
nicohell opened this issue Feb 2, 2024 · 7 comments · Fixed by #2742
Closed

Transaction already in progress #2720

nicohell opened this issue Feb 2, 2024 · 7 comments · Fixed by #2742

Comments

@nicohell
Copy link

nicohell commented Feb 2, 2024

  • Laravel-mongodb Version: 4.1
  • PHP Version: 8.2.15
  • Database Driver & Version: db version v6.0.13
  • PHP MongoDB extension version 1.17.2

Description:

Using firstOrCreate() in a transaction returns an error

Steps to reproduce

$mongodb = DB::connection('app');
$mongodb->beginTransaction();
// user does not exist and will be created
\App\Models\User::firstOrCreate(['username' => 'johncarpenter', 'name' => 'carpenter', 'email' => 'john@example.com']);
$mongodb->rollBack();

Expected behaviour

Manage transaction and commit or rollBack

Actual behaviour

retuns error :
local.ERROR: MongoDB\Driver\Exception\RuntimeException: Transaction already in progress in vendor/mongodb/mongodb/src/Operation/WithTransaction.php:60

Notes

create() works fine
firstOrCreate() and updateOrCreate() do work for updates but do not work for creation as they start a transaction in vendor/mongodb/mongodb/src/Operation/WithTransaction.php

Hack

We went through adding a test in vendor/mongodb/mongodb/src/Operation/WithTransaction.php

 if (!$session->isInTransaction()) {
    $session->startTransaction($this->transactionOptions);
} 
@bisht2050
Copy link
Contributor

bisht2050 commented Feb 7, 2024

Tracked with PHPORM-139.

@GromNaN
Copy link
Member

GromNaN commented Mar 7, 2024

Hello @nicohell, I worked on an implementation of Model::firstOrCreate() using the MongoDB operation findOneAndUpdate (see #2742). Would it solve your issue?

@nicohell
Copy link
Author

nicohell commented Mar 8, 2024

Hello @GromNaN, I don't really understand the implications of #2742 and what would make a difference with findOneAndUpdate ?
Will your implementation of Model::firstOrCreate() using the MongoDB operation findOneAndUpdate manage existing transactions ?

@GromNaN
Copy link
Member

GromNaN commented Mar 8, 2024

The initial issue it that MongoDB doesn't support nested transactions, and Laravel Eloquent Query Builder tries to initiate a transaction in the createOrFirst method.

By changing the implementation, we avoid this nested transaction while providing an optimized implementation.

@nicohell
Copy link
Author

nicohell commented Mar 8, 2024

Do you mean that your implementation will not try to start a new transaction ?

@GromNaN
Copy link
Member

GromNaN commented Mar 8, 2024

Do you mean that your implementation will not try to start a new transaction ?

Yes, because the findOneAndUpdate operation is atomic, so it doesn't need a transaction.

@nicohell
Copy link
Author

Hi @GromNaN

After updating to 4.2.0 we were happy to see that transactions are working fine,

Unfortunately "created_at" and "updated_at" fields are no longer automatically inserted in new records using firstOrCreate, createOrFirst, updateOrCreate, ...

This code creates new record with "created_at" and "updated_at" fields :

$obj = new \App\Models\Parameter; // instantiate model
$obj->created_by = 'nico';
$obj->save();

It breaks between 4.1.3 and 4.2.0

Regards.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants