Pull to refresh

Эпидемия в данных

Reading time2 min
Views808
Хочу рассказать одну историю о том, как однажды никем не предвиденная проблема нанесла финансовый ущерб бизнесу одной крупной корпорации. Я расскажу о причинах возникновения этой проблемы, о том, как мы ее побороли и о том, как решить ее правильно. Надеюсь эта статья поможет проектировщикам избежать подобных ситуаций в будущем.

Есть у нас в базе такая сущность — квота, — это как бы модель заказа. Она имеет заголовок и бесчисленное множество подструктур: линии заказа, рассчитанные цены, всякая сопроводительная информация и т.д. Прежде чем стать заказом, квоты переходят из рук в руки, из отдела в отдел — проверяются и перепроверяются. Сами квоты при этом неизменяемы (immutable), поэтому при любом изменении квоты создается ее копия с новой версией. Кроме того, квоты могут использоваться как шаблоны для других квот. Во всех случаях, когда одна квота порождает другую, все данные исходной квоты наследуются порожденной кроме тех, что изменены. Новая квота может быть так же создана из нескольких путем слияния. Первоначальным источником квот являются несколько фронт-офисных систем.

Так вот, однажды, после развертывания новой версии одной из фронт-офисных систем, сотрудниками отдела аудита была поднята тревога по причине того, что некоторые заказы ушли в обработку с немного заниженными ценами. К расследованию подключили разработчиков, и очень скоро выяснилось, что причиной проблемы с ценами является, как ни банально, ошибка в коде. Сама по себе, ошибка оказалась легко устранимой, но вот повреждение данных, наносимое ей, было нетривиальным. Если коротко, то по всем бизнес-правилам поврежденные квоты были валидны; требовалась особая вычислительная процедура для того, чтобы определить, что дебет с кредитом не сходится. Усугубляло ситуацию то, что при порождении новой квоты из поврежденной, новая квота становилась поврежденной.

Количество поврежденных квот росло со скоростью более тысячи в час, и с каждой новой компания теряла все больше и больше денег. Задача стояла — запретить порождение новых квот поврежденными. Вначале программисты разработали SQL запрос, который со стопроцентной точностью определял поврежденные квоты, но оказалось, что способа запретить квоте порождать другую во всех возможных случаях не существует! Его просто не предусмотрели проектировщики. Единственным доступным способом оказалось — валидировать квоты при загрузке, метить поврежденные и дописать валидатор сохранения, чтобы тот не давал помеченные квоты сохранять. Новая версия фронт-офисной системы была развернута в кратчайшие сроки, и это остановило эпидемию.

С тех пор, в коде нашей системы есть вызов метода, который как печать сдерживает великое зло, живущее в нашей базе. Лучше было бы, конечно, метить квоты в самой базе, но по причинам бюрократического характера руководство посчитало решение достаточным, и базу не стали менять.

Мораль этой истории такова: если вы проектируете структуру данных, которая порождает копии самой себя, предусмотрите простую вещь — флаг, запрещающий ей размножаться. Иначе, когда эта штука мутирует и превратится в чудовище, вам будет нечем с ней бороться.
Tags:
Hubs:
Total votes 67: ↑59 and ↓8+51
Comments22

Articles