Номер транзакции в 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:
- backup и последующее restore очистит TIP полностью, поэтому номера OIT и следующей транзакции будут около 3 (после восстановления БД выполняются несколько транзакций для загрузки данных и построения индексов).
- gfix -sweep вычистит из БД ненужные версии записей и упростит цепочки версий. По умолчанию интервал sweep равен 20,000. Но пока клиенты работают, sweep не может выполниться в монопольном режиме и изменить состояние TIP.
- Если вы не произвели в транзакции никаких действий кроме чтения, то завершайте ее подтверждением (commit). Дело в том, что отмененная транзакция (rollback) создает "заинтересованную" транзакцию. Если в такой транзакции не было изменений, то она только засорит TIP.
В исходном варианте вышеприведенного документа было ошибочно указано предельное значение разницы между OIT и OAT в 1 миллион транзакций. На самом деле эта разница может быть не более 1 миллиарда. Точнее, не больше 1073741824. То, что разница между OIT и OAT или вообще количество транзакций может быть больше миллиона (1,000,000), подтверждается простым тестом:
const
- Создайте базу данных
- Откройте эту базу данных в WISQL или Database Explorer, чтобы создать "заинтересованную" транзакцию.
- Создайте приложение с использованием FreeIBComponents, используя компоненты FIBDatabase, FIBTransation, пару TButton и TLabel:
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;Database "c:\t.gdb"
- Запустите приложение и ждите. Лично у меня терпения хватило дождаться 2,084,586-ой транзакции (работа приложения в течение 4-х часов), при этом статистика по базе данных выглядела следующим образом:
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*