<?xml version="1.0" encoding="UTF-8" ?><oembed><version>1.0</version><provider_name>Чудо{вищные} заметки</provider_name><provider_url>https://miracle.rpz.name</provider_url><author_name>MiRacLe</author_name><author_url>https://miracle.rpz.name/author/miracle/</author_url><title>ты не один</title><html>Приключилась сегодня очень познавательная история, мораль которой должен понимать любой разработчик, детище которого обслуживает более одного пользователя.

В рамках работ по выводу одного &quot;неповоротливого асфальтоукладчика&quot; на земную орбиту были проведены ряд его модернизаций. Испытания на тестовом полигоне показали что машина стала ездить на порядок быстрее и было решено доработки включить в работающий прототип(вроде и не первая космическая, но уже есть чем гордиться!). Но на первом же серьёзном показе зверь-машина с чудо{вищным} грохотом рассыпалась у всех на глазах и я сел в лужу...

А теперь тоже самое, но по-русски, с выражением.
Имеются ряд весьма тяжёлых для веба запросов к БД, результат которых условно не меняется в течении небольшого промежутка времени. Кеширование промежуточных результатов в самой БД нагрузку сняло на СУБД, но скрипты продолжали исправно тягать данные и это порой занимало внушительное время. Было решено результаты эти кешировать на стороне веб-сервера. Как хранилище был использован &lt;a href=&quot;http://php.net/apc&quot;&gt;apc&lt;/a&gt;.

Первоначальный вариант выглядел примерно так:
&lt;pre class=&quot;php:nocontrols&quot;&gt;
if (!$data = cache_get($key)) {
   $data = data_from_db();
   cache_set($key,$data,$expire_time)
}
&lt;/pre&gt;
Без излишеств, просто и со вкусом. Но позже выснилось что &quot;всё не так просто&quot; и в зависимости от некоторых космических характеристик и результатов выборки из базы будет меняется ещё одна переменная (меняется переменная... ого!).
&lt;pre class=&quot;php:nocontrols&quot;&gt;
if (!$data = cache_get($key)) {
   $data = data_from_db();
   cache_set($key,$data,$expire_time);
   $other_data = some_function($data,$env);
   cache_set($other_key,$other_data,$expire_time);
} else {
   $other_data = cache_get($other_key);
}
&lt;/pre&gt;
Аляповато, но, чёрт возьми, работает...
Работало...
Должно было по идее работать...
Но, почему-то оказавшись на боевом, изрядно нагруженном, сервере это не сработало. Вернее это работало...,  но не всё время... По истечении $expire_time периодически пропадали данные для $other_key. При отключении и/или очистке кеша работоспособность восстанавливалась... Кто виноват? Что делать? Кто за всё это ответит?!? Пришлось срочно пошевелить опилками.

Как мы все наверное догадываемся - реальный сервер обслуживает нереально много клиентов, причём не по очереди. И нет совершенно никаких гарантий на то, что между записью $key и $other_key не встрянет какой-либо маленький, но шустрый процесс (хотя нам это и не особо страшно), так же нет никаких оснований полагать что между выборкой $key и $other_key кто-то умный и большой не очистит кеш (целиком, или только $other_key - в данном эпизоде это не имеет значения).
Оснований не было, но я был почему-то твёрдо уверен, что &quot;это если и происходит, то с кем-то другим&quot;. С пониманием проблемы конечно же пришло и простое решение, но ошибка, согласитесь, совсем не тривиальная.

Так что мораль сей басни: помни - ты не один!</html><type>rich</type></oembed>