понедельник, 29 ноября 2010 г. - www.msmirnov.ru

Лекция Андрея Маркеева "Анемичная модель и BLToolkit"

Несколько дней назад Андрей Маркеев читал у нас лекцию "Анемичная модель и BLToolkit".
Видео-запись лекции можно посмотреть здесь или по ссылке.
Мой сайт - www.msmirnov.ru

среда, 24 ноября 2010 г. - www.msmirnov.ru

Как посмотреть sql-запрос, выполняющийся в заданном процессе SQL Server’а

Иногда возникает ситуация, когда на SQL Server’е выполняется сложный запрос, который имеет сложную структуру и отнимает много времени.

Например, это может быть длинная хранимая процедура, содержащая сотни строк кода, вызовы других процедур и т.д. Или, например, job или генеренный запрос, содержащие в себе много запросов.

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

Список процессов, выполняющихся на сервере можно посмотреть через представление master.dbo.sysprocesses которое не содержит текста запроса.

Посмотрим, как мы можем получить запрос, который в данный момент выполняется каком-либо из процессов.

Для начала объявим переменную, содержащую идентификатор нашего процесса:

declare @SPID
set @SPID = 82

В представлении sysprocesses нас будут интересовать следующие поля:
-
sql_handle – ссылка на исполняющийся TDS-пакет.
-
stmt_start – смещение начала строки кода, исполняющейся в данный момент в TDS-пакете, в формате unicode.
- stmt_end – смещение конца строки кода, исполняющейся в данный момент в TDS-пакете, в формате unicode.


Объявим переменные для данных значений и прочитаем их из представления:

DECLARE @sql_handle binary(20), @stmt_start int, @stmt_end int

@sql_handle = sql_handle,
@stmt_start
= stmt_start/2,

@stmt_end
= CASE WHEN stmt_end = -1 THEN -1 ELSE stmt_end/2
END
FROM
master.dbo.
sysprocesses

WHERE spid = @SPID AND ecid = 0

Значения stmt_start и stmt_end делим на два, так как в формате unicode для каждого символа расходуется два байта.

Для получения исполняющегося кода используем функцию fn_get_sql, которая возвращает код запроса для заданной ссылки на пакет.

Данная функция возвращает поле [text] и нам необходимо использовать значения переменных @stmt_start и @stmt_end для того, чтобы получить исполняемый код.

Делаем это следующим образом:

DECLARE @line nvarchar(4000)

SET @line = (SELECT SUBSTRING([text], COALESCE(NULLIF(@stmt_start, 0), 1),
  CASE @stmt_end WHEN -1 THEN DATALENGTH([text]) ELSE (@stmt_end - @stmt_start) END) FROM ::fn_get_sql(@sql_handle)) 

print @line



В результате переменная @line содержит именно ту часть кода, которая исполняется в данный момент.


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


CREATE PROCEDURE PrintCurrentCode
  @SPID int
AS
DECLARE
@sql_handle binary(20), @stmt_start int, @stmt_end
int


SELECT @sql_handle = sql_handle, @stmt_start = stmt_start/2, @stmt_end = CASE WHEN stmt_end = -1 THEN -1 ELSE stmt_end/2 END
FROM
master.dbo.
sysprocesses

WHERE spid = @SPID AND ecid = 0

DECLARE @line nvarchar(4000)

SET @line = (SELECT SUBSTRING([text], COALESCE(NULLIF(@stmt_start, 0), 1),
  CASE @stmt_end WHEN -1 THEN DATALENGTH([text]) ELSE (@stmt_end - @stmt_start) END) FROM ::fn_get_sql(@sql_handle))

print @line
 
Мой сайт - www.msmirnov.ru

вторник, 23 ноября 2010 г. - www.msmirnov.ru

Статус-митинги

Несколько месяцев назад я изменил формат проведения наших статус-митингов.

Статус-митинги я провожу каждую пятницу в 16:30 на протяжении последних нескольких лет (уже не помню скольких, наверное лет 5-ти).

Раньше к каждому статус митингу я готовил небольшой отчет, в котором отмечал над какими задачами мы работали на прошедшей неделе, что у нас получилось, что нет и почему. Кроме того, я готовил план на следующую неделю, в который помещал основные задачи для каждого из членов команды. Данные два документа сохранялись в MS Groove, так что сейчас я могу посмотреть историю всех планов и статус-митингов начиная с 2007 года (до этого Groove не использовался).

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

Несколько месяцев назад я решил изменить формат проведения статус-митингов – вместо меня теперь каждый из членов команды (включая и меня самого) рассказывает чем он занимался прошедшую неделю, что у него получилось, с какими проблемами ему пришлось столкнуться и так далее.
Тут же, в процессе рассказа, имеется возможность кратко обсудить что-то по сказанному, задать какие-то вопросы и так далее.
Т.е. форма проведения стала дискуссионной.

В завершении статус митинга я по прежнему озвучиваю план на следующую неделю для каждого члена команды.

Конечно, длительность статус-митинга благодаря изменениям увеличилась – раньше он занимал около 5-ти минут, теперь около 30-40-ка минут, в зависимости от ситуации.

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

Мой сайт - www.msmirnov.ru

вторник, 16 ноября 2010 г. - www.msmirnov.ru

Он-лайн конференция «Управление проектами 2011. Работа с Заказчиком проекта» День 1.

Сегодня 16 ноября прошел первый день он-лайн конференции “Управление проектами 2011. Работа с Заказчиком проекта”, которую проводила компания “Богданов и партнеры”.

В конференции принимало участие более 100 человек из разных городов России и других стран.

Первый день был имел заглавие “Методика взаимодействия с Заказчиком проекта, тонкости, практические примеры.” 

Первоначально был проведен опрос, “Как давно вы обучались проектному управлению?”
Результаты опроса показались мне интересными:
image

Из интересных докладов, которые удалось послушать, хотелось бы отметить следующие:
1. Владимир Абрамов с докладом “Для чего заказчику разбираться в методологии управления проектами.
Владимир нарисовал собирательный образ наиболее “вредного” заказчика, в котором сосредоточил основные источники проблем в поведении заказчика.
Затем были рассмотрены три основные стратегии поведения заказчика – “Мешать”, “Не мешать” и “Помогать” и их основные характеристики и результаты.
В целом, Владимир показал важность привлечения заказчика к работе над проектом на протяжении всего жизненного цикла, что, в общем-то, давно постулируется в проектом управлении.

Однако, не смотря на все, большинство участников конференции (и я в том числе) посчитало, что заказчики не захотят изучать управление проектами:
image

2.Евгений ПикулевАсимметрия управления проектом. Как пойти одной дорогой с Заказчиком в трудном проекте.
В начале была приведена статистика успешности завершения проектов:
image

На диаграмме видно увеличение количества успешных проектов.

Затем Евгений выделил основные причины возникновения проблем при работе с заказчиком:
image

Далее – основные критерии успешности проекта, с индексом важности каждого из них:
image

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

Завтра будет День 2.

Мой сайт - www.msmirnov.ru

понедельник, 15 ноября 2010 г. - www.msmirnov.ru

Как настроить номер итерации по умолчанию в TFS (Team Foundation Server)

С начала этого месяца мне уже три раза задавали вопрос "Как настроить номер итерации по умолчанию в TFS?".

Ответ на этот вопрос я упонимал здесь, но, поскольку часто спрашивают, решил ответить еще отдельным постом.

Ответ: Никак. Но есть обходной вариант.

Номер итерации хранится в поле Iteration Path, а TFS не позволяет для поля Iteration Path создавать правило DEFAULT, так что значение по умолчанию задавать нельзя. Кроме того, правило PROHIBITEDVALUES задавать также нельзя, поэтому нельзя запретить указывать старые итерации, которые уже остались в прошлом.

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

Для этого поля уже было можно задавать значение по умолчанию и вообще любые правила.
Старое поле Iteration Path на форме Work Item'а я заменил на новое и исправил все запросы к списку work item'ов так, чтобы они использовали новое поле вместо старого.

P.S.
Другие мои посты на тему TFS:
1. Миграция в TFS (Team Foundation Server)
2. Кто ошибку создает - тот ее и проверяет?
3. Нумерация версий продукта в TFS (Team Foundation Server)
4. Учет трудозатрат и отчетность в TFS (Team Foundation Server)
5. Как создать work item в TFS (Team Foundation Server) из письма в Outlook
6. Как поместить свой control на форму Work Item в TFS (Team Foundation Server)
7. Как настроить номер итерации по умолчанию в TFS (Team Foundation Server)
Мой сайт - www.msmirnov.ru

воскресенье, 14 ноября 2010 г. - www.msmirnov.ru

Использование кеша планов запросов SQL Server

Доступ к содержимому кеша планов запросов SQL Server можно получить через представление sys.dm_exec_query_stats.

Используя это представление, можно извлечь такую полезную информацию, как:
- время последнего запуска (поле last_execution_time)
- количество запусков (execution_count)
- общее количество процессорного времени, потраченного на выполнение запроса (total_worker_time)
- нагрузка на подсистему ввода-вывода (total_physical_reads, total_logical_reads, total_physical_writes, total_logical_writes)

Роль идентификатора плана запроса выполняет поле plan_handle.

Значение этого поля можно использовать в качестве входного параметра функции sys.dm_exec_sql_text, которая возвращает текст данного запроса.

В качестве примера - запрос, который отображает 10 наиболее часто запускаемых запросов, что может быть полезно при оптимизации работы с базой данных:

select queries.execution_count, q.dbid, q.[text]
from
(select top 10 qs.plan_handle, qs.execution_count
from sys.dm_exec_query_stats qs
order by qs.execution_count desc) as queries
cross apply sys.dm_exec_sql_text(plan_handle) as q
order by queries.execution_count desc
Мой сайт - www.msmirnov.ru

понедельник, 1 ноября 2010 г. - www.msmirnov.ru

Как поместить свой control на форму Work Item в TFS (Team Foundation Server)

Преамбула.
Вообще говоря, задача, ради которой я решил посмотреть как добавлять свои контролы была такова: довольно часто случается ситуация, когда в текст бага в TFS помещается Stack Trace исключения, которое происходит в работе системы.

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

Проще говоря, на форме ошибки решили поместить кнопку, при нажатии на которую в Visual Studio будет открываться строка кода, указанная в Stack Trace в Details текущего Work Item.

В этом посте я расскажу о том, как добавлять свои котролы на форму Work Item'а, в следующем - как настроить локацию кода.

Создание контрола для Work Item Type.

Прежде всего в студии создаем новый проект типа Class Library который назовем TFSControlsLibrary.

Затем добавляем в проект новый User Control, назовем его LocateCodeControl.

После создания, помещаем на него кнопку LocateCodeButton, с текстом “Locate code”.

После этого имеем новый контрол такого вида:

clear_ctrl


Подключаем в проект две библиотеки:
1. Microsoft.TeamFoundation.WorkItemTracking.Client (путь: C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ReferenceAssemblies\v2.0\Microsoft.TeamFoundation.WorkItemTracking.Client.dll)
2. Microsoft.TeamFoundation.WorkItemTracking.Controls (путь C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies\Microsoft.TeamFoundation.WorkItemTracking.Controls.dll)

Созданный нами контрол LocateCodeControl наследуем от интерфейса IWorkItemControl.

Реализуем интерфейс что называется “по-умолчанию”:


После этого код контрола имеет следующий вид:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.TeamFoundation.WorkItemTracking.Controls;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
 
namespace TFSControlsLibrary
{
public partial class LocateCodeControl : UserControl, IWorkItemControl
{
public LocateCodeControl()
{
InitializeComponent();
}
 
#region IWorkItemControl Members
 
public event EventHandler AfterUpdateDatasource;
public event EventHandler BeforeUpdateDatasource;
 
void IWorkItemControl.Clear() { }
 
void IWorkItemControl.FlushToDatasource() { }
 
void IWorkItemControl.InvalidateDatasource() { }
 
System.Collections.Specialized.StringDictionary IWorkItemControl.Properties {get; set;}
 
bool IWorkItemControl.ReadOnly {get; set;}
 
void IWorkItemControl.SetSite(IServiceProvider serviceProvider) { }
 
public object WorkItemDatasource {get; set;}
 
string IWorkItemControl.WorkItemFieldName {get; set;}
 
#endregion
}
}

Сам контрол на этом готов и если все сделано правильно, то проект должен компилироваться.


Теперь для подключения контрола к TFS в нашем проекте создаем xml-файл с раширением .wicc, который будет использоваться TFS для загрузки библиотеки обработчика контрола. Назовем его LocateCodeControl.wicc


Вот текст файла (как видим, он содержит имя сборки и имя класса контрола.):


<?xml version="1.0" encoding="utf-8" ?>
<CustomControl xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Assembly>TFSControlsLibrary</Assembly>
<FullClassName>TFSControlsLibrary.LocateCodeControl</FullClassName>
</CustomControl>


После всех манипуляций проект будет иметь следующий вид:


sol1


Теперь добавим немного поведения (в качестве теста) для нашей кнопки.

Создадим ей обработчик события Click по которому будем просто отображать Title текущего Work Item’а в MessageBox.

Код обработчика очень простой:

private void LocateCodeButton_Click(object sender, EventArgs e)
{
var ds = WorkItemDatasource as WorkItem;
 
MessageBox.Show(ds.Title);
}


Теперь приступим к тестовому развертыванию нашего контрола.


Для этого необходимо поместить откомпилированную библиотеку контрола и .wcc файл (в нашем случае это файлы TFSControlsLibrary.dll и LocateCodeControl.wicc) в каталог "C:\ProgramData\Microsoft\Team Foundation\Work Item Tracking\Custom Controls\10.0" на каждой машине, на которой будет использоваться данный контрол, так как исполнение кода осуществляется локально, а не на сервере и если этого не сделать, то студия будет писать, что не находит контрол.


После этого можно поместить контрол на форму для какого-либо Work Item Type.

Встроенный в студию Process Editor делать этого не умеет, поэтому придется править xml-файл нашего Work Item'а вручную.

Для этого экспортируем Work Item Type из имеющегося Team Project в локальный xml-файл.

Затем находим этот файл и подключаем в него наш контрол в следующем виде:

<Control Type="LocateCodeControl" />



Затем импортируем наш файл обратно в Team Project.

После этого закрываем Visual Studio и снова открываем ее, иначе она не загрузит наш контрол. Для повторного развертывания наших файлов ее, кстати, также надо будет закрывать, так как она блокирует файлы.

Если все сделано правильно, то при создании бага видим нашу кнопку на форме:


tfs3


При нажатии на кнопку видим наш MessageBox:


tfs4


На этом первичное создание контрола завершено, в следующем посте я расскажу о том, как обеспечить локацию кода по Stack Trace в тексте бага.

P.S.
Другие мои посты на тему TFS:
1. Миграция в TFS (Team Foundation Server)
2. Кто ошибку создает - тот ее и проверяет?
3. Нумерация версий продукта в TFS (Team Foundation Server)
4. Учет трудозатрат и отчетность в TFS (Team Foundation Server)
5. Как создать work item в TFS (Team Foundation Server) из письма в Outlook
6. Как поместить свой control на форму Work Item в TFS (Team Foundation Server)
7. Как настроить номер итерации по умолчанию в TFS (Team Foundation Server)
Мой сайт - www.msmirnov.ru