О самонадеянности
Пишешь что-нибудь на пару раз попользоваться, оно разрастается, начинает использоваться людьми и теряешь возможность внести какие-то исправления, потому что, оказывается, на базе этого уже построили свою функциональность. Но это ещё не самое плохое. Владелец кода in-house разработки может сказать: всё, меня пробило на улучшения: всё поноют, но сделать ничего не смогут. Главное - не смогут помешать изменять. И, в зависимости от количества дипломатических оборотов, которые хочет и может потратить программист, замена лучшего на более лучшее (слышал я такой оборот как-то от барана неместного) пройдёт более или менее безболезненно.
Но если программа (пусть это даже и целая система) писалась в сумерках разума (не важно, по какой причине) и эта программа ушла в production!.. Чтобы умилостивить богов, 90% участников проекта просто обязано застрелиться на рабочих местах (в оригинале - в кабинетах). В самом деле. Допустим, что есть некая вполне тонкая библиотека, абстрагирующая пользователя от того, как выполняется работа с базой данных. Она берёт на себя управление транзакциями, соединениями и прочее всякое. Работает. При тестировании работает just fine. Все вызовы абстрактного сервера данных надёжно защищены критическими секциями, железобетонная корректность открытия и закрытия транзакций также не вызывает никаких сомнений. Работает. Казалось бы.
А теперь посмотрим.
public virtual object SelectScalar()
{
lock(m_CommitSync)
{
int threadId = ThreadId.Value;
object result = null;
try
{
GenericConnection.Open(SQLDataAdapter, threadId);
result = SQLDataAdapter.SelectCommand.ExecuteScalar();
}
catch (Exception ex)
{
DumpException(ex, SQLDataAdapter.SelectCommand.CommandText);
}
finally
{
GenericConnection.Close(threadId);
}
return result;
}
}

Так как я себе верю (а ещё больше - зелёной полоске), то библиотека выводится из круга подозреваемых. Остаётся:
- Процессор
- SQL Server
- Данные
После некоторых колебаний процессор и SQL Server пришлось с сожалением убрать. Оккам показал на данные. Инспекция (чужого) кода показала, что присутствуют:
- Неправдоподобно длинные методы для Insert, Update, Delete
- Для чего-то производятся постоянные выборки всех записей (ок. 600000) из одной популярной таблицы
Да, и ещё ThreadId.Value возвращало Thread.CurrentThread.ManagedThreadId;
Почти день я прозанимался этой проблемой, свалившейся на меня (всё время всё сваливается на меня) из FB (приоритет 1, конечно). Что я могу на её счёт сказать? Раз уж сегодня всё пронумеровано, то вот:
- Длинные методы писались без понимания того, как это будет работать. Всё-таки один клоун Вася (Петя, Коля, Вова и пр.), запуганный своим кодом до того, что боится даже лишний раз нажать на кнопку в готовой (по его мнению) программе - это одно, а толпа тёток, которые без прелюдий ошибаются (кто бы мог подумать) и закрывают окна, когда они начинают скрывать их пасьянс (не говоря уж о том, что им просто обязательно провести собственный обезьяний тест) - это нечто радикально другое. Когда тётки наваливаются на несчастную чахлую тушку программы и начинают её накрячивать вдесятером - тут и выясняется, что у программиста ваще не было представлений о том, что он пишет, для чего и кто использует.
- Излишняя, преступная и вредительская самонадеянность ("такого никогда не может случиться"). Тут и расшифровывать даже не хочу.
Код нельзя просто написать, скомпилировать и дальше неделю пить пиво и пялиться по выходным в телек на новую серию "The Sopranos". Это так примитивно, что неловко даже писать: код должен развиваться. Его надо пересматривать. Он не должен отражать ваше понимание проблемы двухмесячной или двухгодовой давности. Для историй у нас есть SourceOffSite, а для ностальгических соплепусканий ("ах, как всё было просто много лет тому назад"- хрена с два! просто никогда не было!) - http://www.guidebookgallery.org/screenshots/
2 комментария:
Не хотел писать, на самом деле - ведь я тебе, вроде, все с дидлоками объяснил.
Такие методы, как приведенный тобой, вредны для работы с БД. Особенно с учетом вызова из этого метода других методов. На ком ответственность за порядок выполнения в таком случае - неизвестно, sql-код (который РЕАЛЬНО будет исполнятсья на сервере) не контролируется никем. В общем, можно поиметь довольно толстую задницу на самом ровном месте, и дидлок - не самое страшное. Куда страшнее лишний траффик, "переприпаривание" команд и т.п. А синхронизация потоков ВНУТРИ транзакции... Ты бы еще дилоговое окошко во время транзакции показал, и удивлялся бы блокировкам 8)
Я думаю, нужно более серьезно относиться к серверам БД, но раз уж даже гуру программирования Фаулер "забыл" (в толстой книжке про шаблоны проектирования для энтрепрайз-систем) про возможность дидлоков в шаблоне "транзакция" - то что уж с практикующих девелоперов взять?
указатели, стеки, рекурсия, потоки... Я думаю, наседая на эти области, ты часть полезного народа отсеиваешь - есть многое на свете, друг Горацио.
имхо, конечно.
Мне кажется, ты не понимаешь, что такое синхронизация потоков.
А будешь много пиздеть, я вышлю тебе лог работы сервера за сутки, ты на его примере покажешь методы работы, которые "полезны для работы с БД".
Отправить комментарий