Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Нужен пример работы с транзакциями. [D7, IB6.x]


Hmm ©   (2004-11-29 22:45:00) 

Здраствуйте. Запутался в организации транзакций в своём приложении.

На форме лежит IBDataBase, связанный с ним IBTransaction и IBDataset, в котором на событие BeforPost пытаюсь сделать IBTransaction1.starttransaction, а в событии AfterPost IBtransaction1.commit.

Делфя ругается на, то что transaction is active. Ежели я в момент создания формы закрываю транзакцию IBTransaction.active:=false, то приходится лицезреть пустые гриды, видимо мои Dataset-ы тоже закрываются.

В литературе, которую использую я, о транзакциях написанно невнятно, посему прошу объяснить на пальцах, либо кинуть ссылочку - как оргинизовывать транзакции в делфе.


Deniz   (2004-12-01 06:42:00) [1]

Запусти холостой update для записи, которую хочешь заблокировать.
update table set Field1 = Field1 where ID=123
Если транзакцию не закрывать, то другие клиенты получат error при попытке что-то сделать с записью.


Hmm   (2004-11-30 22:31:00) [2]

но ведь FB и IB - не одно и тоже? следовательно такая фишка

Select ... From Table [Where ...] [Order By ...] For Update With Lock в IB 6.5 не пройдет?


msguns   (2004-11-30 12:49:00) [3]

>HSolo ©   (30.11.04 12:15) [11]
Спасибо за справку. У меня 1.0


HSolo   (2004-11-30 12:15:00) [4]

>У меня эта статья настольная ;)
У меня тоже :) Я имею в виду ее дополнение, начиная с этих слов:

Настал момент поговорить о новых возможностях по блокировке, появившихся в FB 1.5.
<cut>
В FB 1.5. включена новая функциональность -

Select ... From Table [Where ...] [Order By ...] For Update With Lock


msguns   (2004-11-30 11:35:00) [5]

>HSolo ©   (30.11.04 11:04) [9]

У меня эта статья настольная ;)
Но в ней описывается как можно сэмулироватьблокировку записи (сей), играя уровнями изоляции транзакций и режимом ожидания. Прямых же блокировок записей в IB с его версионностью нет и быть не может.


HSolo   (2004-11-30 11:04:00) [6]

>В IB можно заблокировать запись ? И даже несколько ?

http://ibase.ru/devinfo/pslock.htm


msguns   (2004-11-30 10:57:00) [7]

>Deniz ©   (30.11.04 06:33) [7]
>Второй пользователь не сможет делать изменения только если первый пользователь явно заблокировал(select with lock или update ...) запись(или несколько) и при этом не завершил транзакцию.  

В IB можно заблокировать запись? И даже несколько ?


Deniz   (2004-11-30 06:33:00) [8]

> DrPass ©   (29.11.04 23:33) [4]
> > Но ведь если один пользователь БД находится в транзакции,
> > то другой не сможет производить изменения в этой БД, до
> > завершения транзакции первым?
>
> Верно.

НЕ ВЕРНО!
Второй пользователь не сможет делать изменения только если первый пользователь явно заблокировал(select with lock или update ...) запись(или несколько) и при этом не завершил транзакцию. Но это достаточно редкий случай.


Hmm   (2004-11-30 00:01:00) [9]

Ну в общем-то ясно, что читать в обязательном порядке... Всеж кое-что уже понятно. Спасибо всем!


DrPass   (2004-11-29 23:33:00) [10]


> Если сказанное выше верно, то возникает вопрос: как наблюдать
> данные в гриде, не находясь в транзакции?

Никак. Любое действие происходит в контексте той или иной транзакции.

> Но ведь если один пользователь БД находится в транзакции,
> то другой не сможет производить изменения в этой БД, до
> завершения транзакции первым?

Верно. Поэтому есть разные варианты, например,
1. Просмотр и добавление/изменении осуществляются в разных транзакциях. При добавлении/изменении пускается EVENT, который сообщает клиенту об изменениях и необходимости перечитать данные
2. Вообще не держишь DataSet открытым, и не используешь DBGrid. Открыл, прочитал, отобразил в какой-нибудь StringGrid, закрыл. Если наборы данных не слишком большие - это замечательный метод. А уведомления - теми же EVENT'ами


jack128   (2004-11-29 23:33:00) [11]

Hmm ©   (29.11.04 23:09) [2]
http://www.ibase.ru/develop.htmчитать всё, в обязательном порядке.


Vemer   (2004-11-29 23:27:00) [12]

Обычно используют 2 транзакции (или больше).

Первая читающая (Read Only, Read Commited),открыта постоянно.

Вторая -  пишущая (без доп. параметров в IBX). Пишущая стартует по мере необходимости, делает свои черные дела и коммитится.

Про это и способы блокировки записей можно почитать на Ibase.Ru


Hmm   (2004-11-29 23:09:00) [13]

Всё это я уже понял, экспериминтирую с открываниями/закрываниями транзакций и датасетов.

Но ведь если один пользователь БД находится в транзакции, то другой не сможет производить изменения в этой БД, до завершения транзакции первым?

Если так, то при такой организации работы база будет всёравно что однопользовательской.

Если сказанное выше верно, то возникает вопрос: как наблюдать данные в гриде, не находясь в транзакции?
Если же не верно, то как обстоят дела на самом деле?


DrPass   (2004-11-29 22:53:00) [14]


> котором на событие BeforPost пытаюсь сделать IBTransaction1.starttransaction,

Если ты делаешь Post, значит, у тебя уже открыт DataSet. А значит, транзакция уже активна. Кстати, StartTransaction вызывается автоматически при открытии датасета (я так понимаю, у тебя это происходит при запуске программы), и этот метод обычно вызывать не требуется.
По поводу Commit - завершая транзакцию ты автоматически закрываешь и все связанные с ней датасеты, поэтому тебе после этого придется опять же лицезреть пустой грид. Чтобы этого не происходило, вызывай CommitRetaining - сохранение изменений на текущий момент без завершения транзакции.


Наверх

Титульная страница Поиск, карта сайта Написать письмо