Laravel_Model_Cache (plug-in for cache optimization for rapidly updated numerical attributes)

Some values of the items in hand often need to be modified
For example, the balance of the wallet table
It is mainly due to some design defects. It is prone to deadlock. Even if there is no lock, it will be very slow
A pit needs to be filled repeatedly
Just want to make a plug-in that is less intrusive and does not need to change the source code too much
The specified properties of the Model can be cached, and all changes can only be changed in the cache
When it's all right, make an overall plan and save it to the database together
So there was this project
Then I actually have a poor foundation, so I hope you can help me a lot if you have any questions
Then if this thing has predecessors' shoulders to stand on, please tell me, I don't have to be so tired to write for a long time, arigado

Laravel_Model_Cache (plug-in for cache optimization for rapidly updated numerical attributes)



composer require linty/laravel_model_cache


The plug-in uses all caches. The Redis storage function used by the Cache is to proxy a field of an object of a model. The Cache is used to maintain for a period of time (temporarily 10 minutes). All modifications are made in the Cache to optimize performance


  1. A new queue named model cache is added to the queue to maintain fields. When the model cache is created for the first time, a Job with a delay of 10 minutes will be created, and the database will be saved after 10 minutes (or longer)
  2. In the Model class to be used, use:
    use ModelCacheTrait;
    At this time, the getAttributeFromArray method of the model will be intercepted for some cache reading operations
  3. Add - > cache () after the original model, for example
 $wallet = Wallet::query()->first()->cache();
  1. If a transaction is required:
    $wallet = Wallet::query()->first()->cache(true);

    This function is only valid when the attribute is numeric. Other errors should be reported because no judgment is written. I wrote this article at 4 a.m. next time

Detailed use

Modify the data and use Redis agent

 $wallet = Wallet::query()->first()->cache(); $wallet->balance_cache = 100; 
 // Modify the value of the balance field and start caching    

Modify balance or balance_ The effect of cache is equivalent, which is to modify the cache
Recommended use_ The cache suffix is used to distinguish the modification of ordinary models to avoid old eyes
At this time, the general model Wallet:: query() - > first() - > balance; The latest cached data will also be obtained
Priority: cache > Database

The agent modifies the data, and the common model also modifies the data

 $wallet1 = Wallet::query()->first()->cache(); 
 $wallet1->balance_cache = 88; 
 // The changes here will not be saved to the database until 10 minutes later

 $wallet = Wallet::query()->first(); info($wallet->balance);      
 // But you can read it here 

 $wallet->balance = 200; 
 // The new value saved here is 200. If you discard the previous modification, the cache will become invalid

 // 200. If you update other models, it will be forcibly synchronized here

What should I do if I don't want to modify it? Open a transaction

 $wallet1 = Wallet::query()->first()->cache(true);
 // Here, you have to save it to be useful

 $wallet1->balance_cache = 88;  
 // Originally 200, this is an invalid modification

 $wallet = Wallet::query()->first(); 
 info($wallet->balance);  // 200
 $wallet1 = Wallet::query()->first()->cache(true); 
 $wallet1->balance_cache = 88;
 $wallet = Wallet::query()->first(); 
 info($wallet->balance);  // 88  

About transaction commit

 $wallet = Wallet::query()->first();
 $wallet->balance = 0; $wallet->save();   // The initial value is 0,
 $wallet1 = Wallet::query()->first()->cache(true); $wallet1->balance_cache += 10;
 debug($wallet1->balance_cache); // 10

 $wallet2 = Wallet::query()->first()->cache(true); $wallet2->balance_cache += 10;
 // 10. The transaction in the previous step was not committed

 $wallet1->saveCache(); debug($wallet2->balance_cache);
 // 20. After submitting the transaction of the previous step, you can get the latest value. Don't let big brother's money be wasted

 $wallet3 = Wallet::query()->first()->cache(true); $wallet3->balance_cache += 10;
 debug($wallet3->balance_cache); // 20. Because wallet2 didn't submit it, it won't have an effect if it doesn't submit

 debug($wallet1->balance_cache); // 20, 1 can also get the latest value here. Since 2 is not submitted, here is 20
 debug($wallet2->balance_cache); // 30, 2. You can get the latest value here

 debug($wallet1->balance_cache); // 30, 1. You can get the latest value here
 debug($wallet3->balance_cache); // 30, 3. You can get the latest value here

Keywords: Laravel Cache

Added by Big_Rog on Sun, 12 Dec 2021 22:25:05 +0200