вопрос по работе триггеров

SEYD
Дата: 01.08.2012 17:50:15
Добрый день,


Есть таблица employees с primary key EID, этот EID заполняется в триггере. Сейчас просто накручивается счетчик на 1 и используется это значение в качестве нового EID.
Необходимо сделать так, чтоб перед тем, как выдать новый EID производиласть проверка на предмет попадания его значения в один из диапазонов и в случае отрицательного результата накручивать до первого значения следующего диапазона. Диапазоны хранятся в таблице ranges (fromid, toid).

этот процесс я представляю следующим образом (код триггера на вставку):

tmpid = gen_id(gen_employees, 1); 

select count(*) 
  from ranges 
  where tmpid between fromid and toid
  into :a;

if (a=0) then
begin
  select min(fromid)
    from ranges
    where tmpid<fromid
    into :b;

  if (b is null) then exception employees_range_not_enough;

  tmpid = gen_id(gen_employees, b-tmpid);  
end;

new.eid = tmpid;



как отработает триггер при множественной вставке из нескольких транзакций? т.е. пока не отработает триггер по первой вставке, следующая вставка сидит и ждет? или же это может происходить параллельно? тогда может случиться так, что при истечении диапазона два триггера могут два раза промотать генератор ...
WildSery
Дата: 01.08.2012 18:04:17
Никто никого не ждёт. Генератор может быть откручен запросто, как ты и опасаешься.
Вариантов обхода кроме мьютекса (настоящего или имитации через блокировку) нет.
Dimitry Sibiryakov
Дата: 01.08.2012 18:06:02

SEYD
тогда может случиться так, что при истечении диапазона два триггера могут два раза
промотать генератор ...

Да, почти наверняка.

Posted via ActualForum NNTP Server 1.5

SEYD
Дата: 01.08.2012 18:06:39
WildSery
Вариантов обхода кроме мьютекса (настоящего или имитации через блокировку) нет.


это как?
WildSery
Дата: 01.08.2012 19:51:02
На сайте ibase была статья о пессимистической блокировке.
SEYD
Дата: 02.08.2012 10:51:42
WildSery
На сайте ibase была статья о пессимистической блокировке.


нашел, прочитал, только не понимаю как это связано с моей задачей?
SEYD
Дата: 02.08.2012 11:23:09
а что если создать генератор - флаг работы триггера и в начале триггера добавить:
while (gen_id(gen_employees_flg_busy,1)>0) do gen_id(gen_employees_flg_busy,-1);


а в конце
gen_id(gen_employees_flg_busy,-1);


м?
WildSery
Дата: 02.08.2012 12:32:04
SEYD,

Mutex.
Но не советую - его реализация через UDF есть хождение по лезвию, поскольку нарушает логику работы сервера.

Блокировка строки апдейтом - это более безопасная штука, подходит для сериализации чего угодно.
SEYD
Дата: 02.08.2012 14:17:41
WildSery
Mutex.
Но не советую - его реализация через UDF есть хождение по лезвию, поскольку нарушает логику работы сервера.

А предложенный выше мной вариант с дополнительным генератором не есть ли мьютекс по сути? Каждая новая вставка крутится в while do в триггере и ждет пока закончится предыдущая.
UDF не хочу, тем более если это еще и опасно.

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

Не понимаю какая связь. Если я заблокирую строку, то как это повлияет на вставку новой строки?
WildSery
Дата: 02.08.2012 16:13:38
SEYD
А предложенный выше мной вариант с дополнительным генератором не есть ли мьютекс по сути?
Во-первых, то, что ты написал, не взлетит, надо по-другому.
Во-вторых, нет, не то же самое что мьютекс, поскольку между проверкой значения генератора и установкой его в "блокированное" положение проходят сотни наносекунд, куда запросто успеет попасть проверка другой вставки.