You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm using lockForUpdate, but it obviously won't work if there is caching in-between, because it is not possible to tell the DB to lock something if we never even reached the DB right? 😸
The solution is simply resort to raw query i.e. using the \DB::xxx statements.
Here is an example that I use to bypass Lada Cache and then transform result array back into model object:
$table = (newYourAmazingModel())->getTable();
$items = \DB::table($table)
->lockForUpdate()
->where(' ... filter results ... ')
->orderBy('id', 'asc')
->take(15)
->get();
// Transform array to YourAmazingModelforeach ($itemsas$key => $item) {
$items[$key] = (newYourAmazingModel())->newFromBuilder((array)$item);
}
$items = collect($items);
// Now you can loop $items and update them as necessary to release the row locks
Note: Do not forget to wrap your code in transaction so that you can revert the lock in case of exception and avoid deadlocks.
The text was updated successfully, but these errors were encountered:
P.S. In case someone wants to use JOINs in their SQL query then the previous example might give unexpected issues (at least for me with PostgreSQL) because DB is confused about which table is used for row locking.
Here is an example how to avoid that:
$table = (newYourAmazingModel())->getTable();
$table_alias = 'yam';
$items = DB::table("{$table} AS {$table_alias}")
->select("{$table_alias}.*")
->leftJoin(' ... left JOIN some other table ... ')
->where(' ... filter results by JOINed table ... ')
->where(' ... filter results by main (yam) table ... ')
->orderBy("{$table_alias}.id", 'asc')
->take(15);
// This is same thing as "lockForUpdate()", but to avoid conflicts with other// tables when using JOINs we specify which exact table is used for row locking.$sql = "{$items->toSql()} FOR UPDATE OF {$table_alias}";
$items = $items->getConnection()->select($sql, $items->getBindings(), false);
// Transform array to YourAmazingModelforeach ($itemsas$key => $item) {
$items[$key] = (newYourAmazingModel())->newFromBuilder((array)$item);
}
$items = collect($items);
// Now you can loop $items and update them as necessary to release the row locks
Using locking mechanisms requires usage of raw sql queries to bypass Lada Cache.
https://laravel.com/docs/5.6/queries#pessimistic-locking
I'm using lockForUpdate, but it obviously won't work if there is caching in-between, because it is not possible to tell the DB to lock something if we never even reached the DB right? 😸
The solution is simply resort to raw query i.e. using the \DB::xxx statements.
Here is an example that I use to bypass Lada Cache and then transform result array back into model object:
Note: Do not forget to wrap your code in transaction so that you can revert the lock in case of exception and avoid deadlocks.
The text was updated successfully, but these errors were encountered: