Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Firebird, Interbase > Помогите разобраться с генераторами


Автор: RSV 25.10.2005, 08:14
CDatabase m_db;
CRecordset m_rs;
CDBVariant var;
int n_Id;

char sql[] = "SELECT GEN_ID(Client_gen, 0) FROM RDB$DATABASE";
m_rs.m_pDatabase = &m_db;

m_rs.Open(CRecordset::forwardOnly, sql, CRecordset::readOnly);
m_rs.GetFieldValue((short)0, var);
n_Id = var.m_iVal;
m_rs.Close();

Вопрос. Во всех статьях о генераторах описано, что таким способом
(SELECT GEN_ID(Client_gen, 0) FROM RDB$DATABASE) можно узнать текущее
значение генератора Client_gen. Почему в моем приложении значение
var.m_iVal при любом количестве вызова GEN_ID(Client_gen, 1)постоянно
равно одному и тому же значению (28728).

Версия: Firebird 1.5.
Способ доступа: VC++;

Автор: МихаилК 25.10.2005, 11:16
В GEN_ID вторым параметром идет приращение. В приведенном тобой примере он равно 0, поэтому и возвращается одно и тоже число (текущее значение генератора), попробуй изменить на 1, например.
Кроме того, по непроверенным данным (слышал краем глаза) в FB1.5.0 Classic не видно изменение значения генератора после вызова функции GEN_ID в другой транзакции, до подтверждения текущей. Еще раз повторюсь - информация непроверенная, но есть некоторая вероятность ее подлинности.
Удачи

Автор: Петрович 25.10.2005, 15:39
Цитата
Кроме того, по непроверенным данным (слышал краем глаза) в FB1.5.0 Classic не видно изменение значения генератора после вызова функции GEN_ID в другой транзакции, до подтверждения текущей.

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

Автор: МихаилК 25.10.2005, 16:41
Цитата
Сильно сомневаюсь. Иначе, вообще теряется смысл существования генераторов. Их основная ценность в том, что они живут вне механизма транзакций.

Я тоже сомневался, но один программист из нашей группы разработчиков говорит, что это так. Причем я видел собственными глазами, что в другой транзакции действительно генератор не изменял своего значения до подтверждения изменяющей транзакции. Мы с ним долго поудивлялись и решили Classic не использовать. Остается правда вероятность, что он где-то напортачил с вызовами (детално я не вникал), но вероятность этого не слишком высока. Может еще тестировалось на какой-то не релизной версии FB - сейчас мы это уже не узнаем.

Автор: Петрович 25.10.2005, 21:30
Повторюсь несколько иначе. Если высказанное тобой предположение верно, то с таким сервером не сможет корректно работать ни одна серьезная программа!
Генераторы обычно используются для получения уникальных идентификаторов записей. Следовательно, при таком поведении, идентификаторы полученные в двух паралельных транзакциях совпадут. Т.е., при сохранении будем иметь гаррантированное нарушение правила уникальности ID.
Лет пять, а то и более, работаю с разными версиями IB/FB, но с таким ни разу не сталкивался.
Не обижайся, но думаю что это был косяк у твоего коллеги.
Без публичной демонстрации примера где такой эффект воспроизводится, никогда в такое не поверю.

Автор: nnm 25.10.2005, 21:39
Цитата(short)
The short keyword designates a 16-bit integer.

Цитата(int)
On 32-bit platforms, the keyword int specifies a 32-bit signed integer.

2 МихаилК: Не вводи, пожалуйста, народ в заблуждение - генераторы работают вне контекста транзакции и не зависят от версии сервера. Честное слово smile

Автор: МихаилК 26.10.2005, 07:53
Цитата(nnm @ 25.10.2005, 21:39)
2 МихаилК: Не вводи, пожалуйста, народ в заблуждение - генераторы работают вне контекста транзакции и не зависят от версии сервера. Честное слово smile

Наверное ты в чем то прав: столь серьезное предположение просто необходимо было подкреплять примером. К сожалению сейчас нет времени заняться исследованием данного вопроса, так что не предлагаю верить мне на слово. Я просто высказал предположение исходя из имеющихся у меня данных. Кроме того я прекрасно осознаю, что генераторы просто ОБЯЗАНЫ работать вне контекста транзакций, так что мне данный случай тоже представляется скорее всего глюком.
P.S. Если все-таки время появится, постараюсь воспроизвести пример и выложить тут (если конечно удасться узнать и найти версию билда FB, использовавшегося в предыдущий раз).

Автор: RSV 26.10.2005, 08:06
Цитата
Цитата
Кроме того, по непроверенным данным (слышал краем глаза) в FB1.5.0 Classic не видно изменение значения генератора после вызова функции GEN_ID в другой транзакции, до подтверждения текущей.

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

Я извиняюсь, что вклинился в вашу беседу, но на мой вопрос о генераторах я так
и не получил ответ. Почему у меня не получается на клиенте определить
текущее значение генератора? Где моя ошибка?

Автор: Guest 26.10.2005, 17:23
Объясни мне, тёмному (я не знаю VC++):
var.m_iVal - это int, адрес int или что-то ещё ?

Автор: Петрович 26.10.2005, 18:29
Цитата(RSV @ 26.10.2005, 09:06)
Почему у меня не получается на клиенте определить
текущее значение генератора? Где моя ошибка?

К сожалению, мои знания C++ не велики. В их рамках, мне кажется что все написано правильно. Хотя, не знаю что будет если возникнет ошибка при выполнении запроса - ты я смотрю вроде никак это не обрабатываешь.

Цитата(RSV @ 25.10.2005, 09:14)
Во всех статьях о генераторах описано, что таким способом
(SELECT GEN_ID(Client_gen, 0) FROM RDB$DATABASE) можно узнать текущее
значение генератора Client_gen.

Правильность этого ты можешь проверить в любой программе типа IBExpert, IBConsole, и пр.

Автор: Alex 1.11.2005, 09:14
http://www.ibase.ru/devinfo/generator.htm

Автор: syan66 4.5.2006, 11:36
Значит, экспериментировал как мог... По-разному-всякому.
На форме лежит 2 TIBQuery и 2 TIBTransaction. 
В IBQuery1: 'SELECT GEN_ID(CLIENT_GEN, 0) FROM RDB$DATABASE', 
IBQuery2: 'SELECT GEN_ID(CLIENT_GEN, 1) FROM RDB$DATABASE' 
Две транзакции, по одной на каждый TIBQuery для чистоты эксперимента.
Транзакции явно не стартуют и не коммитятся, DefaultAction taRollback.

Необновление значения IBQuery1.Fileds[0] при открытии/закрытии запроса 1 получилось только в случае, многократного IBQuery2.Open без Close smile

Выводы: 
1. Генераторы меняются вне контекста транзакции
2. Ошибка в вызовах GEN_ID, 1
 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)