Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 read for update  [new]
KlugCZ
Member

Откуда: Ostrava-CZ
Сообщений: 338
Добрый день,

имеется два приложения первое - многопоточное, второе - однопоточное. В каждом потоке первого запускается хп типа:

begin
   ...
   SET TRANSACTION ISOLATION LEVEL SNAPSHOT;

   begin transaction

   while @flag
   begin
      @flag=!@flag

      set cursor @v_cur = CURSOR LOCAL SCROLL for select t2.ID
                                from t1 , t2 (UPDLOCK)

      FETCH NEXT FROM @v_cur INTO @v_id
      
      while @@FETCH_STATUS = 0
      begin
          ...
          insert into t1(ID) values (@v_id)
          ...
          set @flag=true

          FETCH NEXT FROM @v_cur INTO @v_id
      end

   end

   commit transaction
   ...
end

ISOLATION LEVEL SNAPSHOT и UPDLOCK используется чтобы два параллельных процесса многопоточного приложения не могли обрабатывать одни и те же записи из t2, но при этом чтобы остальные приложения и процессы могли читать оттуда данные.

А теперь вопрос: правильно ли использование снапшота и апдлока для достижения описанной функциональности. Если нет, то подскажите как правильно.
13 май 11, 14:12    [10647698]     Ответить | Цитировать Сообщить модератору
 Re: read for update  [new]
Glory
Member

Откуда:
Сообщений: 104751
А зачем блокировать все записи курсора, если вы их обрабатываете по одной ?
13 май 11, 14:24    [10647834]     Ответить | Цитировать Сообщить модератору
 Re: read for update  [new]
KlugCZ
Member

Откуда: Ostrava-CZ
Сообщений: 338
Glory,

собственно цель заблокировать только записи в t2 и только те которые достались этому процессу. Там курсор гораздо сложнее.
set cursor @v_cur = CURSOR LOCAL SCROLL for select t2.ID
                             from t1 right outer join t2 (UPDLOCK) on ...
                                         inner join t3 ...
                             where ...
13 май 11, 14:30    [10647897]     Ответить | Цитировать Сообщить модератору
 Re: read for update  [new]
Glory
Member

Откуда:
Сообщений: 104751
KlugCZ
Glory,

собственно цель заблокировать только записи в t2 и только те которые достались этому процессу. Т

Если они ему уже достались, то зачем их блокировать то ?
Кто/что распределяет записи между процессами ?
13 май 11, 14:33    [10647922]     Ответить | Цитировать Сообщить модератору
 Re: read for update  [new]
KlugCZ
Member

Откуда: Ostrava-CZ
Сообщений: 338
Glory,

t1 и t2 связаны по id, в t2 находится определение величины, в t1 ее значения для каждого момента времени. Значение величины может зависеть от значений других величин. Процесс записывает в t1 значение независимой величины, а далее начинается свистопляска. Нужно получить все зависимые величины, для рассчета которых уже известны входные данные, рассчитать и снова сохранить в t1 и так делать пока не убедимся, что больше нету зависимых величин которые можно посчитать.

Так вот запись независимой величины происходит в начале хп, 100% известно, что никакие два запущенных процесса не могут записывать значения одной величины. Блокировка делается для того чтобы параллельные процессы не начали рассчитывать одну и ту же зависимую величину. Например a1, a2, a3 - независимые a4=a1+a2, a5=a1+a3, a6=a4*a5. А далее процесс 1 (п1) записывает а1, одновременно п2 записывает а2, так вот тот кто первый выяснит, что можно посчитать а4, тот пусть и считает, а второй закончится. Далее пока считалось а4, п3 пишет а3 и теперь кто первый "заберет" для рассчета а5 тот его и считает и потом соответственно и а6.
При этом всем есть другие приложения, которые просто показывают данные из t1 и t2.

Теперь, надеюсь, будет понятнее.
13 май 11, 15:20    [10648481]     Ответить | Цитировать Сообщить модератору
 Re: read for update  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Есть несколько советов.

1. Не использовать курсоры.
2. Никогда не использовать курсоры.
3. Стараться поменьше использовать хинты, особенно UpdLock. (Точнее использовать по назначению, сильно подумав)
4. Писать декларативно, пусть машина сама решает когда надо распараллелить. Очень часто програмизды ошибаются в своём видении эффективного плана выполнения.
KlugCZ
Блокировка делается для того чтобы параллельные процессы не начали одновременно рассчитывать одну и ту же зависимую величину. Например:

a1, a2, a3 - независимые
a4, a5, a6 - зависимые:

a4=a1+a2
a5=a1+a3
a6=a4*a5.
Версию сервера укажите.
Выкиньте зависимые величины нафиг. Поставьте вместо них индексированное вью. Проблем ровно 0.

Вы задали вопрос, теперь с вас:
автор
процесс 1 (п1) записывает а1, одновременно п2 записывает а2, так вот - тот кто первый выяснит, что можно посчитать а4, тот пусть и считает, а второй закончится.
Что за задача такая, что потоки стартуют независимо? Базовые величины приходят из разных источников?
13 май 11, 21:31    [10650610]     Ответить | Цитировать Сообщить модератору
 Re: read for update  [new]
KlugCZ
Member

Откуда: Ostrava-CZ
Сообщений: 338
Mnior,

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

Выкинуть зависимые величины и заменить их вьюхой нельзя, т.к. они рассчитываются при помощи различных ХП, рассчеты конфигурирует пользователь.

Про курсоры знаю, но тут к сожалению без него не обойтись.

MS SQL2008R2
17 май 11, 17:33    [10666601]     Ответить | Цитировать Сообщить модератору
 Re: read for update  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
KlugCZ
они рассчитываются при помощи различных ХП, расчеты настраивает пользователь
+
Это нормально. Говно-код вездесущ. Даже уже стал сомневаться что вообще где-то в мире есть адекватные системы.

Всё что не меняет данные не может быть XP. Ошибки всегда порождают за собой другие и порой вынужденные.
Ваш КО.
Жаль что вы не расскажете принципы этих расчётов. Вдруг вы меня убедите (что вряд ли), что существует реальная система где невозможно декларативно написать. А если не расскажите, то будем считать что KlugCZ просто не умеет писать декларативно. Ок.

У вас проблема синхронизации процессов N->1. Метод Патёрн бутылочное горлышко:
CREATE PROCEDURE [dbo].[spN100500_AddParam]
	 @ID	Int
	,@Type		TinyInt
	,@Value		SQL_Variant
AS BEGIN
	BEGIN TRAN TrN100500;
		INSERT	dbo.ParamValue			(ID,Type,Value)
		SELECT	I.*
		FROM	(VALUES(@ID, @Type, @Value)) I	(ID,Type,Value)
		WHERE	Exists(	SELECT 1 FROM dbo.ParamType	T
		LEFT JOIN (	SELECT * FROM dbo.ParamValue	V WITH(Serializable) WHERE V.ID = @ID
		UNION ALL	SELECT I.*		)	V ON V.Type = T.ID
				WHERE	T.ID IS NULL	);

		IF (@@RowCount = 0) BEGIN	-- Опа, мы последние
			INSERT	dbo.ParamValue	( ID, Type, Value)
			VALUES			(@ID,@Type,@Value);

			EXEC dbo.spN100501_GoMegaPuperCalc @ID;
		END
	COMMIT TRAN TrN100500;
END
GO
Если хотите чтобы нормально (без всяких извращённых SNAPSHOT-ов) читались данные остальными потоками даже в случае последней вставки (при очень корявой долгой процедуре расчётов dbo.spN100501_GoMegaPuperCalc), то передавайте в неё параметр (@ID,@Type,@Value), считая его за добавленный, а под конец уже вставляйте.

Это вам привёл лишь пример. Смысл простой - вставка очередного параметра происходит при условии отсутствия хотя бы одного другого. WITH(Serializable) вам подсказывает, что на этот микро-момент локируется на изменение весь диапазон параметров по объекту @ID.
17 май 11, 23:05    [10668325]     Ответить | Цитировать Сообщить модератору
 Re: read for update  [new]
KlugCZ
Member

Откуда: Ostrava-CZ
Сообщений: 338
Mnior,

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

Проблема была решена абсолютно иначе.
18 май 11, 14:10    [10671381]     Ответить | Цитировать Сообщить модератору
 Re: read for update  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
KlugCZ
онлайн мониторинга солнечных электростанций
И какая там нафиг динамика смены формул?
Может "проектировщик" не вкурил в предметную область?

А то у горе-программистов чешутся руки написать универсального монстра.
18 май 11, 19:55    [10674157]     Ответить | Цитировать Сообщить модератору
 Re: read for update  [new]
KlugCZ
Member

Откуда: Ostrava-CZ
Сообщений: 338
Mnior
И какая там нафиг динамика смены формул?
Может "проектировщик" не вкурил в предметную область?

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

На этом позвольте откланяться и закончить ненужную дискуссию, проектирование очередной говносистемы не терпит ожидания знаете ли.
19 май 11, 16:03    [10679331]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить