Номер транзакции в IB хранится как 32-разрядное целое число, поэтому количество транзакций легко может достигнуть 2 миллиардов. Это справедливо для InterBase на всех платформах.
Однако существует ограничение, когда IB не может стартовать новую транзакцию если разница между новым номером транзакции и старейшей заинтересованной транзакцией (OIT. Подробнее на эту тему см. документ) составляет 2 миллиарда (знаковое целое, MaxInt). "Заинтересованной" является транзакция "подтвержденная", "отменная", "активная", или "отложенная".
Утилита GSTAT покажет вам значения OIT и следующей транзакции. Эти номера не должны сильно отличаться. Если разница между ними выросла в 50,000 и более, то это является предупреждающим сигналом о том, что в БД находится транзакция, мешающая OIT повысить свой номер.
Примите во внимание, что информация о транзакциях (TIP) копируется в память, распределяемую IB для каждого клиента. Если там много транзакций (900,000 и выше), то это уже значительный объем памяти. Кстати, именно благодаря копии TIP для клиента IB обрабатывает транзакции Repeatable Read: каждый клиент получает состояние всех транзакций на момент старта собственной транзакции. Состояния транзакций в клиентской копии TIP указывают, может клиент видеть конкретную версию записи или нет: если версия создана с идентификатором транзакции, которая в TIP указана как committed (подтвержденная), то версия видна.
Вы можете несколькими способами предотвратить "застой" номера OIT:
В исходном варианте вышеприведенного документа было ошибочно указано предельное значение разницы между OIT и OAT в 1 миллион транзакций. На самом деле эта разница может быть не более 1 миллиарда. Точнее, не больше 1073741824. То, что разница между OIT и OAT или вообще количество транзакций может быть больше миллиона (1,000,000), подтверждается простым тестом:
1. Создайте базу данных
2. Откройте эту базу данных в WISQL или Database Explorer, чтобы создать
"заинтересованную" транзакцию.
3. Создайте приложение с использованием FreeIBComponents, используя
компоненты FIBDatabase, FIBTransation, пару TButton и TLabel:
const stop: boolean = False; cnt: integer = 0;
procedure TForm1.Button1Click(Sender: TObject); begin FIBDatabase1.Connected:=True; while not stop do begin Inc(cnt); FIBTransaction1.StartTransaction; FIBTransaction1.Commit; Label1.Caption:=IntToStr(cnt); Application.ProcessMessages; end; end;
procedure TForm1.Button2Click(Sender: TObject); begin Stop:=True; end;
4. Запустите приложение и ждите.
Лично у меня терпения хватило дождаться 2,084,586-ой транзакции (работа приложения в течение 4-х часов), при этом статистика по базе данных выглядела следующим образом:
Database "c:\t.gdb" Database header page information: Flags 0 Checksum 12345 Generation 2084607 Page size 1024 ODS version 9.1 Oldest transaction 1044689 Oldest active 1044690 Oldest snapshot 1044690 Next transaction 2084600 Bumped transaction 1 Sequence number 0 Next attachment ID 0 Implementation ID 16 Shadow count 0 Page buffers 0 Next header page 0 Creation date Aug 25, 1999 12:17:52 Variable header data: Sweep interval: 0 *END*