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

Nested transactions are not supported by this client. #232

Open
matthewjumpsoffbuildings opened this issue Oct 8, 2024 · 13 comments
Open

Comments

@matthewjumpsoffbuildings
Copy link
Contributor

matthewjumpsoffbuildings commented Oct 8, 2024

When I upgraded from v7 to v8 of this driver, I found that suddenly code that worked fine in v7 is now throwing the "Nested transactions are not supported by this client." error from google/cloud-spanner/src/Database.php:912

I know that in the ManagesTransactions trait there is the following block

 // Since Cloud Spanner does not support nested transactions,
        // we use Laravel's transaction management for nested transactions only.
        if ($this->transactions > 0) {
            return parent::transaction($callback, $attempts);
        }

Which I would assume is supposed to stop nested transaction calls from throwing the error I am getting, and in v7 it does seem to work, but something has changed in v8 that is making it no longer work?

I know its probably hard to debug without a demo repository, but I am hoping you have a some idea what might have changed with transaction handling from v7 to v8 that might be causing this

If it is helpful here is the error and call stack

 Nested transactions are not supported by this client. {"userId":"03faf8f5-0dde-4c65-bc4e-52f823b6e69e","exception":"[object] (BadMethodCallException(code: 0): Nested transactions are not supported by this client. at /vendor/google/cloud-spanner/src/Database.php:912)
[stacktrace]
#0 /vendor/colopl/laravel-spanner/src/Concerns/ManagesTransactions.php(76): Google\\Cloud\\Spanner\\Database->runTransaction(Object(Closure), Array)
#1 /vendor/colopl/laravel-spanner/src/Connection.php(555): Colopl\\Spanner\\Connection->Colopl\\Spanner\\Concerns\\{closure}()
#2 /vendor/colopl/laravel-spanner/src/Concerns/ManagesTransactions.php(75): Colopl\\Spanner\\Connection->withSessionNotFoundHandling(Object(Closure))
#3 /vendor/colopl/laravel-spanner/src/Connection.php(346): Colopl\\Spanner\\Connection->transaction(Object(Closure))
#4 /vendor/laravel/framework/src/Illuminate/Database/Connection.php(536): Colopl\\Spanner\\Connection->affectingStatement('update `media` ...', Array)
#5 /vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(3859): Illuminate\\Database\\Connection->update('update `media` ...', Array)
#6 /vendor/colopl/laravel-spanner/src/Query/Builder.php(63): Illuminate\\Database\\Query\\Builder->update(Object(Illuminate\\Support\\Collection))
#7 /vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(1115): Colopl\\Spanner\\Query\\Builder->update(Array)
#8 /vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(1238): Illuminate\\Database\\Eloquent\\Builder->update(Array)
#9 /vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(1155): Illuminate\\Database\\Eloquent\\Model->performUpdate(Object(Illuminate\\Database\\Eloquent\\Builder))
#10 /vendor/spatie/laravel-medialibrary/src/MediaCollections/Models/Media.php(515): Illuminate\\Database\\Eloquent\\Model->save()
#11 /vendor/spatie/laravel-medialibrary/src/MediaCollections/Models/Media.php(293): Spatie\\MediaLibrary\\MediaCollections\\Models\\Media->saveOrTouch()
#12 /vendor/spatie/laravel-medialibrary/src/Conversions/Actions/PerformConversionAction.php(49): Spatie\\MediaLibrary\\MediaCollections\\Models\\Media->markAsConversionGenerated('thumb')
#13 /vendor/spatie/laravel-medialibrary/src/Conversions/FileManipulator.php(71): Spatie\\MediaLibrary\\Conversions\\Actions\\PerformConversionAction->execute(Object(Spatie\\MediaLibrary\\Conversions\\Conversion), Object(App\\Models\\Media), '/Users/matt/Dev...')
#14 /vendor/laravel/framework/src/Illuminate/Collections/Traits/EnumeratesValues.php(257): Spatie\\MediaLibrary\\Conversions\\FileManipulator->Spatie\\MediaLibrary\\Conversions\\{closure}(Object(Spatie\\MediaLibrary\\Conversions\\Conversion), 0)
#15 /vendor/spatie/laravel-medialibrary/src/Conversions/FileManipulator.php(70): Illuminate\\Support\\Collection->each(Object(Closure))
#16 /vendor/spatie/laravel-medialibrary/src/Conversions/Jobs/PerformConversionsJob.php(29): Spatie\\MediaLibrary\\Conversions\\FileManipulator->performConversions(Object(Spatie\\MediaLibrary\\Conversions\\ConversionCollection), Object(App\\Models\\Media), false)
#17 /vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Spatie\\MediaLibrary\\Conversions\\Jobs\\PerformConversionsJob->handle(Object(Spatie\\MediaLibrary\\Conversions\\FileManipulator))
#18 /vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#19 /vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(95): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#20 /vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#21 /vendor/laravel/framework/src/Illuminate/Container/Container.php(690): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#22 /vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(128): Illuminate\\Container\\Container->call(Array)
#23 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(144): Illuminate\\Bus\\Dispatcher->Illuminate\\Bus\\{closure}(Object(Spatie\\MediaLibrary\\Conversions\\Jobs\\PerformConversionsJob))
#24 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(119): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Spatie\\MediaLibrary\\Conversions\\Jobs\\PerformConversionsJob))
#25 /vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(132): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#26 /vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(124): Illuminate\\Bus\\Dispatcher->dispatchNow(Object(Spatie\\MediaLibrary\\Conversions\\Jobs\\PerformConversionsJob), false)
#27 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(144): Illuminate\\Queue\\CallQueuedHandler->Illuminate\\Queue\\{closure}(Object(Spatie\\MediaLibrary\\Conversions\\Jobs\\PerformConversionsJob))
#28 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(119): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Spatie\\MediaLibrary\\Conversions\\Jobs\\PerformConversionsJob))
#29 /vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(123): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#30 /vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(71): Illuminate\\Queue\\CallQueuedHandler->dispatchThroughMiddleware(Object(Illuminate\\Queue\\Jobs\\SyncJob), Object(Spatie\\MediaLibrary\\Conversions\\Jobs\\PerformConversionsJob))
#31 /vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(102): Illuminate\\Queue\\CallQueuedHandler->call(Object(Illuminate\\Queue\\Jobs\\SyncJob), Array)
#32 /vendor/laravel/framework/src/Illuminate/Queue/SyncQueue.php(76): Illuminate\\Queue\\Jobs\\Job->fire()
#33 /vendor/laravel/framework/src/Illuminate/Queue/SyncQueue.php(52): Illuminate\\Queue\\SyncQueue->executeJob(Object(Spatie\\MediaLibrary\\Conversions\\Jobs\\PerformConversionsJob), '', '')
#34 /vendor/laravel/framework/src/Illuminate/Database/DatabaseTransactionRecord.php(69): Illuminate\\Queue\\SyncQueue->Illuminate\\Queue\\{closure}()
#35 /vendor/laravel/framework/src/Illuminate/Collections/HigherOrderCollectionProxy.php(65): Illuminate\\Database\\DatabaseTransactionRecord->executeCallbacks()
#36 [internal function]: Illuminate\\Support\\HigherOrderCollectionProxy->Illuminate\\Support\\{closure}(Object(Illuminate\\Database\\DatabaseTransactionRecord), 1)
#37 /vendor/laravel/framework/src/Illuminate/Collections/Arr.php(605): array_map(Object(Closure), Array, Array)
#38 /vendor/laravel/framework/src/Illuminate/Collections/Collection.php(789): Illuminate\\Support\\Arr::map(Array, Object(Closure))
#39 /vendor/laravel/framework/src/Illuminate/Collections/HigherOrderCollectionProxy.php(64): Illuminate\\Support\\Collection->map(Object(Closure))
#40 /vendor/laravel/framework/src/Illuminate/Database/DatabaseTransactionsManager.php(96): Illuminate\\Support\\HigherOrderCollectionProxy->__call('executeCallback...', Array)
#41 /vendor/colopl/laravel-spanner/src/Concerns/ManagesTransactions.php(178): Illuminate\\Database\\DatabaseTransactionsManager->commit('spanner-emulato...', 1, 0)
#42 /vendor/colopl/laravel-spanner/src/Concerns/ManagesTransactions.php(94): Colopl\\Spanner\\Connection->performSpannerCommit()
#43 [internal function]: Colopl\\Spanner\\Connection->Colopl\\Spanner\\Concerns\\{closure}(Object(Google\\Cloud\\Spanner\\Transaction))
#44 /vendor/google/cloud-spanner/src/Database.php(968): call_user_func(Object(Closure), Object(Google\\Cloud\\Spanner\\Transaction))
#45 [internal function]: Google\\Cloud\\Spanner\\Database->Google\\Cloud\\Spanner\\{closure}(Object(Closure), Object(Google\\Cloud\\Spanner\\Session\\Session), Array)
#46 /vendor/google/cloud-core/src/Retry.php(80): call_user_func_array(Object(Closure), Array)
#47 /vendor/google/cloud-spanner/src/Database.php(986): Google\\Cloud\\Core\\Retry->execute(Object(Closure), Array)
#48 /vendor/colopl/laravel-spanner/src/Concerns/ManagesTransactions.php(76): Google\\Cloud\\Spanner\\Database->runTransaction(Object(Closure), Array)
#49 /vendor/colopl/laravel-spanner/src/Connection.php(555): Colopl\\Spanner\\Connection->Colopl\\Spanner\\Concerns\\{closure}()
#50 /vendor/colopl/laravel-spanner/src/Concerns/ManagesTransactions.php(75): Colopl\\Spanner\\Connection->withSessionNotFoundHandling(Object(Closure))
#51 /vendor/laravel/nova/src/Http/Controllers/ResourceUpdateController.php(37): Colopl\\Spanner\\Connection->transaction(Object(Closure))
@taka-oyama
Copy link
Collaborator

Can you at least narrow down to the exact version? thanks.

@matthewjumpsoffbuildings
Copy link
Contributor Author

matthewjumpsoffbuildings commented Oct 9, 2024

Sure, 7.4.2 worked fine, but 8.1.2 up to 8.2.0 did not. I didnt try 8.1.0-8.1.1 because the updateOrInsert signature wasnt compatible with the version of Laravel 11 I had, but I can also try and downgrade Laravel if you think that testing 8.1.0-8.1.1 would help narrow it down

@taka-oyama
Copy link
Collaborator

Can you try updating only google/cloud-spanner while using 7.4.2?
Also, if that works, then please try updating to 8.0.0 and let me know if the error still occurs.

@matthewjumpsoffbuildings
Copy link
Contributor Author

I used the latest google/cloud-spanner in both (1.86.0)

I will test 8.0.0 shortly and let you know, thanks

@taka-oyama
Copy link
Collaborator

As far as I can tell, I haven't changed anything transaction related v7.4.2...v8.1.2. So I'm guessing there might be changes in related libraries.

@matthewjumpsoffbuildings
Copy link
Contributor Author

I just tested 8.0.0 and the same issue occurs, "Nested transactions are not supported by this client" is thrown

@taka-oyama
Copy link
Collaborator

Could be something that changed on laravel's side. Can you try lowering laravel 11's version to 11.0.0?

@matthewjumpsoffbuildings
Copy link
Contributor Author

Just tried Laravel 11.0.0 with version 8.0.0 of this driver, still throwing

@taka-oyama
Copy link
Collaborator

what was laravel/framework 's version when you were on laravel-spanner v7.4.2?

@matthewjumpsoffbuildings
Copy link
Contributor Author

Heres something interesting - on my fork I removed the Laravel 11 requirement from composer.json and installed v8.2.0 in a Laravel 10 project, and it doesn't throw the error any more

So it looks like something has changed in Laravel between 10 and 11 that is making passing the nested transaction handling up the inheritance chain no longer work as expected?

@matthewjumpsoffbuildings
Copy link
Contributor Author

matthewjumpsoffbuildings commented Oct 9, 2024

what was laravel/framework 's version when you were on laravel-spanner v7.4.2?

I was on version 10.48.22

(pardon the edit, copy pasted the wrong value)

@taka-oyama
Copy link
Collaborator

At this point I really can't do much without reproducible code.
I can tell from the logs that you have some sort of job running in SyncQueue.
Is the job dispatched after a commit?

@matthewjumpsoffbuildings
Copy link
Contributor Author

matthewjumpsoffbuildings commented Oct 9, 2024

Yes, basically what is happening in that call stack is a model is being created via a Laravel Nova resource update request, but I also have the spatie/laravel-medialibrary package associated with said model, which I guess internally uses SyncQueue to commit to its own media table when editing models that have associated media.

I will see what I can do about creating a demo repo

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

No branches or pull requests

2 participants