Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to solve the problem of Redis queue exception caused by Observer event in Laravel

2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article mainly explains "how to solve the problem of Redis queue exception caused by Observer events in Laravel". Interested friends may wish to have a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn how to solve the problem of Redis queue exception caused by Observer events in Laravel.

1. Business logic

After creating a new model, use the Observer model event Created to push into the asynchronous SMS sending queue

App\ Http\ Controllers\ UsersController

Public function store (User $user) {\ DB::beginTransaction (); try {$input = request ()-> validated (); $user- > fill ($input); $user- > save (); / / do something. / / other data table operations\ DB::commit ();} catch ($e\ Exception) {\ DB::rollBack ();}}

App\ Observers\ UserObserver

Class UserObserver {public function created (User $user) {dispatch (new SmsQueue ($user));}} 2, exception found

Business unit reported that occasionally a user could not receive SMS notification, so I checked the log and found that there was an occasional error exception: No query results for model [App\ Models\ User]. Indicates that the corresponding model cannot be found

I should not knock, I am after the creation of the model before the queue call. Then carefully check the business code and guess that it should be affected by the transaction.

Verify the conjecture:

Public function store (User $user) {\ DB::beginTransaction (); try {$input = request ()-> validated (); $user- > fill ($input); $user- > save (); / / do something. / / other data table operations sleep (3); / / commit the transaction after three seconds\ DB::commit ();} catch ($e\ Exception) {\ DB::rollBack ();}}

Sure enough, after waiting for three seconds, the submission queue exception has been triggered at 100%.

3. Cause analysis.

If the method $user- > save () succeeds in creating the data, it will also trigger the scheduler to execute the model events one by one.

The model is pushed to the queue in the event, while the queue process continuously consumes the data in the queue.

In most cases, if the do something processing speed is normal, the queue process will run as usual.

If there is an occasional delay during the do something phase, the transaction has not yet been commit and the queue has started to consume the new model; therefore, the above error is raised.

Then when I searched for Github Issues records, I found that this issue had been raised in an Issue in 2015, and finally added support for transaction model events in Laravel 8.x; learnku.com/docs/laravel/8.x/eloqu... No relevant instructions seem to be found in the community documents ~

Since my version is 6.x, I can't use this new feature [crying].

4. Solve the exception 1. Modify MySQL transaction isolation level (not recommended)

This involves the transaction isolation level of MySQL. The default isolation level of the InnoDB engine is REPEATABLE READ, and the differences between these levels can be found in the official documentation.

Switching the isolation level to READ UNCOMMITTED can solve this problem, but in order to prevent bigger problems, I advise you not to use this method.

two。 Increase event snooping

Check the source code to know that the corresponding event will be called after the transaction is completed, so you only need to increase the listening for the event.

New class App\ Handlers\ TransactionHandler

Class TransactionHandler {public array $handlers; public function _ construct () {$this- > handlers = [];} public function add (\ Closure $handler) {$this- > handlers [] = $handler;} public function run () {foreach ($this- > handlers as $handler) {$handler ();} $this- > handlers = [];}}

Create an auxiliary function app/helpers.php

If (! Function_exists ('after_transaction') {/ * * operate after transaction ends * * / function after_transaction (Closure $job) {app ()-> singletonIf (\ App\ Handlers\ TransactionHandler::class, function () {return new\ App\ Handlers\ TransactionHandler ();}); app (\ App\ Handlers\ TransactionHandler::class)-> add ($job);}}

Create a listening App\ Listeners\ TransactionListener

Namespace App\ Listeners;use App\ Handlers\ TransactionHandler;class TransactionListener {public function handle () {app (TransactionHandler::class)-> run ();}}

Bind to listen on App\ Providers\ EventServiceProvider

Namespace App\ Providers;use App\ Listeners\ TransactionListener;use Illuminate\ Database\ Events\ TransactionCommitted;use Illuminate\ Database\ Events\ TransactionRolledBack;use Illuminate\ Foundation\ Support\ Providers\ EventServiceProvider as ServiceProvider;;class EventServiceProvider extends ServiceProvider {/ * The event listener mappings for the application. * * @ var array * / protected $listen = [TransactionCommitted::class = > [TransactionListener::class], TransactionRolledBack::class = > [TransactionListener::class]];}

Change the calling method App\ Observers\ UserObserver

Class UserObserver {public function created (User $user) {after_transaction (function () use ($user) {dispatch (new SmsQueue ($user));});}} at this point, I believe you have a deeper understanding of "how to solve the Redis queue exception problem caused by Observer events in Laravel". You might as well do it in practice! Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report