April 2008 Blog Posts

Transact-SQL & API Functions

28 April 2008 |

При работе с SQL Server транзакции обычно оформляются одним из двух способов. Либо в самом SQL запросе, либо средствами API, к примеру в ADO.NET.

Достаточно давно читал, что комбинировать два вида этих транзакций не желательно. Но откуда точно эта информация и насколько она соответствует истине сказать не мог. Ситуация начала потихоньку прояснятся. Скорее всего эта информация отсюда.

Each transaction must be managed by only one of these methods. Using both methods on the same transaction can lead to undefined results. For example, you should not start a transaction using the ODBC API functions, and then use the Transact-SQL COMMIT statement to complete the transaction. This would not notify the SQL Server ODBC driver that the transaction was committed. In this case, use the ODBC SQLEndTran function to end the transaction.

Но вот, что конкретно это означает. Означает ли, что нельзя сочетать эти подходы ни при каких условиях или что в Transact-SQL надо всегда использовать именованные транзакции, или что-то другое... осталось не понятным.

Если кто знает правильный ответ, скажите, интересно.

IE автозаполнение

25 April 2008 |

В IE есть такая замечательная функциональность как автозаполнение формы. Т.е. когда один раз ввел в форму данные, в следующей раз при вводе подскажут продолжение. Выглядит это примерно так:

IE_autoform

Удобно и не навязчиво. Единственное что раздражает, это наличие заведомо ошибочных вариантов, и то что они постоянно появляются. К примеру как показано на рисунке. Оказывается от этого можно легко избавиться, достаточно выделить не нужный вариант и нажать кнопку Del, все просто.

Долгое время, старался не обращать на это внимание, но в последнее время стало сильно раздражать, вот и пришлось разобраться.

TableAdapterManager Bug

23 April 2008 |

В VS 2008 в генератор типизированных DataSet-ов, добавился замечательный класс TableAdapterManager. Предназначен он для каскадных операций сохранения данных в базу данных из DataSet, такая функциональность напрашивалась и очевидно полезна.

Добавить то добавили, но пользоваться ей фактически нельзя до выхода SP1 для VS2008. Причина небольшой bug, который можно разглядеть не вооруженным глазом. Самый важный метод UpdateAll содержит вот такой код:

if (((workConnection.State & global::System.Data.ConnectionState.Closed)
== global::System.Data.ConnectionState.Closed)) {
workConnection.Open();
workConnOpened = true;
}


Как говорил Остап Бендер "Убивать надо таких знатоков". Данное условие выполняется ВСЕГДА, для жизни это означает что вы не можете передавать свои открытые соединения, а значит не можете делать эти вызовы в одной транзакции с другими, и значит, что на данный момент полезен этот класс только на игрушечных задачах.


Bug хорош тем, что можно посмотреть какие реально ошибки допускают разработчики Microsoft, причины этих ошибок. Причина в том что ConnectionsState.Close это 0, и в том что не выполняются элементарное требование к оформлению enum: 0 элемент всегда должен иметь семантику null, т.е. не определенности, обычно это выглядит как: None/Undefined/Nothing/... Bug обещают исправить в SP1 для VS 2008, который выйдет уже скоро.

SQL Server 2005: TableDiff.exe

21 April 2008 |

Задача учёта изменений в схеме базы данных решается достаточно хорошо средствами SQL Server Management Studio. Где есть возможность при сохранении каждого изменения в схеме данных параллельно сохранять скрипт его выполняющий. Но этого не достаточно, необходимо ещё отслеживать изменение справочных данных, имеются в виду данные находящиеся в базе данных в начальный момент времени. И вот для этого случая полезна утилита TableDiff.exe, она входит в поставку SQL Server 2005, позволяет сравнивать данные в двух таблицах, на разных серверах/базах данных и получать скрипт, этой разницы. Утилита консольная, но для тех кто не хочет разбираться для неё есть UI.

Конечно если задачи связанные с поддержкой версионности данных возникают часто, и в них задействовано большое количество человек. То решать их надо с помощью других инструментальных средств, к примеру Visual Studio Team System 2008 Database Edition.

Developers, Developers, Developers...

19 April 2008 |

Что является результатом работы программиста? Около 80% людей ответит - программа, и это нормально. Но становиться грустно, когда люди занимающиеся разработкой программного обеспечения отвечают таким образом. А как вы считаете, что является результатом работы программиста?

Наверняка вы слышали что это такое, об этом часто говорят в институте, школе, умных книжках. Ответ очень простой: результатом работы программиста является исходный код. Исходный код не есть программа. Пользователями исходного кода являются совсем другие агенты, чем пользователи программы, исходный код предоставляет совсем другие возможности. Пользователи исходного кода делятся на две категории: машины и люди. Машины это компиляторы, интерпретаторы, люди это, как правило, разработчики или сам автор кода. Исходный код должен пытаться одновременно удовлетворить потребности этих двух категорий.

К чему повторять эти банальности? К тому что, в жизни люди почему то про них забывают. Часто ли вы встречали менеджеров, которые выдвигают требования к коду, иногда встречаются политики связанные к покрытием кода модульными тестами, прохождением статического анализатора кода, обзорами кода, но обычно они свидетельствуют не о заботе о качестве кода, а о проблемах в организации процесса разработки. Часто можно встретить разработчика, который свято верит, что если функциональность присутствует, то свою работу он выполнил, и не важно какой там код написан.

Помните: Результатом работы разработчика является исходный код. Именно за него платят деньги, два разных исходных кода выполняющих одну и ту же функциональность могут очень сильно различаться в цене.

Как то всё мрачно получилось, поэтому старая шутка.

Assembla

18 April 2008 |

Что делать если ваш проект перерастает по количеству участников 3-х человек и люди работают удалённо? Если есть возможность развернуть соответствующую инфраструктуру, то вопрос решается тривиально. Но так бывает не всегда. Налчие в интеренет сервисов решающих эту проблему, не вызывает сомнений.

Если вы столкнулись с такой проблемой, то рекомендую http://www.assembla.com/. Тут есть все что надо для счастья: SVN хостинг,  WIKI, форум, чат, файлохранилище, issue трекер. И всё это до 500Мб бесплатно.

Relax

14 April 2008 |

В суд с иском на Русскую православную церковь обратился екатеринбургский правозащитник Алексей Конев. В августе прошлого года он заплатил деньги за чин отпевания своего родственника и остался недоволен процедурой отпевания. Конев обвинил РПЦ в том, что она (цитирую) «нарушает права потребителей». Как сообщают СМИ, в ответ на это обвинение представитель ответчика заявил, что нарушения прав потребителя не было, поскольку (цитирую) «потребителем услуг в данном случае являлся упокоившийся».

Парадокс Монти Холла

11 April 2008 |

Из статьи узнал о любопытной задачке, известной как парадокс Монти Холла.

Представьте, что вы стали участником игры, в которой вы находитесь перед тремя дверями. Ведущий, о котором известно, что он честен, поместил за одной из дверей автомобиль, а за двумя другими дверями — по козе. У вас нет никакой информации о том, что за какой дверью находится. Ведущий говорит вам: «Сначала вы должны выбрать одну из дверей. После этого я открою одну из оставшихся дверей, за которой находится коза. Затем я предложу вам изменить свой первоначальный выбор и выбрать оставшуюся закрытую дверь вместо той, которую вы выбрали вначале. Вы можете последовать моему совету и выбрать другую дверь, либо подтвердить свой первоначальный выбор. После этого я открою дверь, которую вы выбрали, и вы выиграете то, что находится за этой дверью.»

Вы выбираете дверь номер 3. Ведущий открывает дверь номер 1 и показывает, что за ней находится коза. Затем ведущий предлагает вам выбрать дверь номер 2. Увеличатся ли ваши шансы выиграть автомобиль, если вы последуете его совету?

Грустно осознавать, но сразу не понял ответ, моя интуиция вошла в противоречие с разумом, страшно подумать, может я гуманитарий. А Вы?

Пчёлы против мёда

10 April 2008 |

В современным информационном мире, чтобы иметь хоть какое-то своё мнение, необходимо всю поступающую информацию обдумывать и критически рассматривать. Если этого не делать, то затруднительно быть разумным человеком. Приведём пример, сейчас стало популярны компании в которых представители каких-либо социальных групп призывают к борьбе:

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

Чувствуете противоречие, а ведь все это не случайность здесь есть закономерность, обусловленная законами природы. Думаете это преувеличение? Включите телевизор/откройте газету, попробуйте не впитывать информацию, а обдумывать, прослушать какое нибудь выступление и просто подумать, кто что говорит.

.Net Shared Application Settings

08 April 2008 |

Достаточно давно (с входом VS 2005) появилась технология управления пользовательскими настройками приложения для платформы .NET. Обычно для разработчика это выглядит как элемента проекта с расширением .settings, настройки можно редактировать встроенным инструментом, в результате с помощью утилиты SettingsSingleFileGenerator генерируется класс - оболочка для доступа к настройкам. Настройки бывают двух видов пользовательские и уровня приложения. Пользовательские настройки могут сохраняться и загружаться программно в стандартизованное локальное хранилище \Documents and Settings\<user>\Local Settings\Application Data\<organization>\<applicationName>\<Version>\user.config. Но настройки уровня приложения доступны только для чтения, и не существует встроенного механизма для сохранения/загрузки настроек уровня приложения.

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

Суть решения состоит в следующем. За сохранение настроек отвечают классы наследники от SettingsProvider, по умолчанию используется LocalFileSettingsProvider, который как раз и сохраняет настройки уровня пользователя. Поэтому нам необходимо создать свой SettingsProvider. Настройки уровня приложения вынести в отдельный файл но в тот же класс, добавить для свойства настройки аксессор set, и установив атрибут свойства SettingsProviderAttribute в котором указать наш новый провайдер. После этих процедур появиться возможность загружать/сохранять данные уровня пользователя. В качестве места хранения данных используется стандартное место: Documents and Settings\All Users\Application Data\<organization>\<application name>\<version>\app.config. Источник вдохновения здесь.

Будьте внимательны решение хотя и является рабочим, но носит демонстрационный характер. И наконец самое главное Исходный Код.

Мосэнергосбыт - граница миров

07 April 2008 |

Недавно спокойное течение жизни было прервано звонком из мосэрергосбыт. Вежливый автоинформатор любезно сообщил: что у меня имеется задолженность и что её надо оплатить иначе согласно договору оказание услуги может быть прекращено, для выяснения подробностей позвоните по такому то номеру телефона.

Согласитесь, такой звонок портит настроение, особенно если ты платишь регулярно и аккуратно. Всё ещё надеясь на чудо звоню по указанному номеру телефона, где мне любезно сообщают, что оператор ответит не раньше через 20 минут, ответа дождаться не смог. После этого в воображении промелькнули картины, очередей в управе, дезе, паспортном столе и других подобных учреждений, встречавшихся на жизненном пути. Цепляясь за призрачную надежду, захожу на сайт Мосэнергосбыт, и что же мы даже не поверили что только что звонил в туже организацию. Здесь вам и виртуальная приёмная, в которой ответы на вопросы оперативно выкладываются, здесь и SMS сервис, воспользовавшись, которым можно узнать дату/сумму последнего платежа и вашу задолженность. И даже не важно что SMS сервис платный, и не ясно почему бы не сделать такой же E-mail сервис бесплатным, и почему доступ к этой информации платен, важно, что это другой мир, мир с лицо в котором есть человеческие черты.

Конечно же я пользуюсь SMS сервисом, и обнаруживаю что никакой задолженности нет, и показания этого сервиса совпадают с квитанциями. Это не вызывает никакого удивления или ещё каких то чувств, ведь в запасе есть виртуальная приёмная. Пишу сообщение в виртуальную приёмную, и буквально через 2 дней получаю ответ:

Вопрос:
29.03.2008 г. позвонил автоинформатор и сказал, что у меня задолженность по оплате. Плачу я всегда вовремя, ежемесячно. Для проверки воспользовался сервисом "SMS-справка". Согласно ему последний платёж поступил 20.03.2008 г. на сумму 395 руб. 08 коп. за 02.2008 г. показания 12929 день и никакой задолженности нет. С чем связан звонок автоинформатора?

Ответ:
Уважаемый Алексей Сергеевич,
по состоянию лицевого счета на 20.03.2008 г. показания счетчика 12929 Вам было сформировано корректирующее извещение на сумму переплаты 2 руб. 66 коп. Получить информацию о текущем состоянии лицевого счета Вы можете, сообщив показания счетчика, в Контактном центре ОАО «Мосэнергосбыт» по тел.: 8-800-555-0-555.

Ответ конечно пришёл из другого мира, но как на это можно обижаться, только слёзы умиления. Как говорил поэт "Зима не даром злиться прошла её пора Весна в окно стучится и гонит со двора".

DDD > TDD is't it?

02 April 2008 |

Мода на Agile методологии разработки программного обеспечения привела к тому, что многие разработчики перестали серьёзно относится к проектированию, как таковому. Сейчас у разработчиков голова забита TDD (Test Driven Development), XP, SCRUM, Refactoring, Pair programming, Collective Code Ownership, Simple Design и другими подобными. На ряду с этим представления о design достаточно смутные, большинство не уделяют внимание тому, что сказано в той же методологии XP:

Designing
From the point of view of simplicity, one could say that system development doesn't need more than coding, testing and listening. If those activities are performed well, the result should always be a system that works. In practice, this will not work. One can come a long way without designing but at a given time one will get stuck. The system becomes too complex and the dependencies within the system cease to be clear.
One can avoid this by creating a design structure that organizes the logic in the system. Good design will avoid lots of dependencies within a system; this means that changing one part of the system will not affect other parts of the system.

From this

Парадокс ситуации заключается в том, что именно design является важнейшем показателем качества продукта, и именно ради него все и делается. Design не появиться ниоткуда если им не заниматься специально, серебряной пули не существует. Бывает грустно видеть людей которые обложили код модульными тестами, настроили ежедневные сборки и поэтому уверены, что design продукта замечательный.

Господа относитесь ко всему критичны, не будьте однобоки, не становитесь заложниками современных тенденций, одним словом будьте разумны. Если вы почувствовали однобокость, и так вообще для приятного проведения времени советую почитать брошюрку Domain Driven Design Quickly.