Страница 1 из 1

Вопрос по тразакциям - читающим и пишущим.

Добавлено: 27 июл 2008, 12:58
KKJ
Здравствуйте.
Пишу многопользовательское приложение с использованием Firebird v2.0.1.12855 и Delphi 7.
Соответственно столкнулся с вопросом правильной организации использования транзакций.
Для доступа к базе данных и к данным использую встроенные в Delphi компоненты IBX.

На основной форме есть Grid, привязанный к DataSet, к которому привязана "читающая" транзакция ibReadTransaction с параметрами

Код: Выделить всё

read_committed
rec_version
nowait.
DataSet использую исключительно для чтения данных, то есть только Select.

Для редактирования данных использую IBSQL, с которым ассоциирую "пишущую" транзакцию ibWriteTransaction с такими же параметрами.

По ibWriteTransaction.Commit делаю

Код: Выделить всё

DataSet.Close;
DataSet.Open;
Данные, отображающиеся в Gride, меняются только у того пользователя, который делает обновление.

У других пользователей данные меняются только тогда, если в код добавляю

Код: Выделить всё

DataSet.Open;
ibReadTransaction.Commit;
DataSet.Close;

Мой вопрос:
логично ли так поступать, есть ли какие-нибудь альтернативы, сильно ли нагружается сервер?

Добавлено: 27 июл 2008, 13:03
KKJ
И ещё вопрос:
Как правильно будет сделать обновление на других пользователях, при изменении данных: либо организовать на форме кнопку, что-то типа "Обновить", либо по таймеру?

Заранее большое спасибо.

Добавлено: 27 июл 2008, 13:57
kdv
к которому привязана "читающая"
это не читающая. это пишущая. См.
www.ibase.ru/devinfo/ibx.htm
У других пользователей данные меняются только тогда, если в код добавляю
не может такого быть. значит параметры у транзакции на чтение НЕ выставлены. Иначе, как нормальная read_committed, она бы видела любые чужие committed-изменения при перевыполнении запроса.
Тут уже был один такой гражданин с подобной проблемой, выяснилось что у него в коде было непонятно что наверчено, и вовсе не в транзакциях было дело :)
логично ли так поступать, есть ли какие-нибудь альтернативы, сильно ли нагружается сервер?
читать www.ibase.ru/devinfo/ibx.htm , однозначно.
и еще, мелкий совет. Называй транзакции покороче. если у тебя их всего две на все приложение, то TR и TW будут идеальными именами. Если больше - в имени задавай смысл или контекст транзакции а не что это "WriteTransaction". Иначе упаришься в коде их упоминать.

Добавлено: 27 июл 2008, 13:59
Attid
KKJ писал(а):И ещё вопрос:
Как правильно будет сделать обновление на других пользователях, при изменении данных: либо организовать на форме кнопку, что-то типа "Обновить", либо по таймеру?
Да.
DataSet.Open;
ibReadTransaction.Commit;
DataSet.Close;
достаточно было бы и просто закрыть\открыть.
По ibWriteTransaction.Commit делаю
DataSet.Close;
DataSet.Open;
может
ibWriteTransaction.Commit;
DataSet.Open;
меньше на одну строчку и точно комитится. а то поставит кто нибуть дефол действие роллбек и плакали твои данные.

Добавлено: 27 июл 2008, 14:01
Attid
kdv писал(а):Иначе, как нормальная read_committed, она бы видела любые чужие committed-изменения при перевыполнении запроса.
сдается мне что он имеет ввиду что "само" в гриде не меняется.

Добавлено: 27 июл 2008, 14:47
KKJ
Attid писал(а):
kdv писал(а):Иначе, как нормальная read_committed, она бы видела любые чужие committed-изменения при перевыполнении запроса.
сдается мне что он имеет ввиду что "само" в гриде не меняется.
да да да - имеенно в гриде! возможно я не правильно сформулировал

т.е. я при нажатии на кнопку "Добавить данные" - делаю вот так

DM.ibReadTransaction.Commit;
DM.ibDataSet.Open;

т.е. как раз и делаю перевыполнение.

Добавлено: 28 июл 2008, 09:27
Attid
тебе ответили и дали ссылочку почитать.

и как говорит Дмитрий порассуждать логически, ты открыл датасет, получил набор данных, он у тебя локально, и пока ты его не обновишь, он сам не обновится.

кнопке рефрешь самый лучший вариант, вместо переоткрытя по таймеру можешь попробывать события, только не обновляй на каждый чих, а по условию запускаешь таймер на 5 секунд на переоткрытие, если таймер уже запущен то ничего не делаешь. по таймеру обновляешь и отключаешь его.

Добавлено: 28 июл 2008, 10:05
KKJ
Attid писал(а):тебе ответили и дали ссылочку почитать.

и как говорит Дмитрий порассуждать логически, ты открыл датасет, получил набор данных, он у тебя локально, и пока ты его не обновишь, он сам не обновится.

кнопке рефрешь самый лучший вариант, вместо переоткрытя по таймеру можешь попробывать события, только не обновляй на каждый чих, а по условию запускаешь таймер на 5 секунд на переоткрытие, если таймер уже запущен то ничего не делаешь. по таймеру обновляешь и отключаешь его.
да я все понял уже...спасибо...
на каждый чих обновлять не буду, ты имеешь ввиду события от Firebird - и в триггере посылать, да?я правильно понял?

Добавлено: 28 июл 2008, 11:53
kdv
ты имеешь ввиду события от Firebird - и в триггере посылать, да?я правильно понял?
как показывает практика, лучше дать юзеру кнопку или хоткей для "Обновить данные".

Добавлено: 28 июл 2008, 12:17
KKJ
kdv писал(а):
ты имеешь ввиду события от Firebird - и в триггере посылать, да?я правильно понял?
как показывает практика, лучше дать юзеру кнопку или хоткей для "Обновить данные".
так и сделал : Обновить(клв. F5)

Добавлено: 28 июл 2008, 12:20
KKJ
Ещё микровопрос "исходя из практики":
если идет работа со справочниками около 10 штук (просмотр, редакт, удал) - корректно ли использовать один DataSet - и в зависимости от глобальной переменной открывать/редак./удалять данные - или корректнее будет созадть датасет на каждый спр.

Добавлено: 28 июл 2008, 12:44
Attid
KKJ писал(а):Ещё микровопрос "исходя из практики":
если идет работа со справочниками около 10 штук (просмотр, редакт, удал) - корректно ли использовать один DataSet - и в зависимости от глобальной переменной открывать/редак./удалять данные - или корректнее будет созадть датасет на каждый спр.
дело привычки, но если формы разные то ИМХО лучше на каждой иметь свой датасет\транзакции

Добавлено: 28 июл 2008, 13:14
kdv
10 штук (просмотр, редакт, удал) - корректно ли использовать один DataSet
это скорее вопрос удобства. Если попытки экономии ухудшают код - значит экономить не надо.
Например. Если у меня есть DataModule, то для выполнения разных запросов от случая к случаю (служебных) я использую один TIBSQL.
Если же мне надо датасет и грид - я их создаю там где надо, не задумываясь чтобы использовать конкретный датасет еще для какого-то другого грида.

Если же окно редактирования справочников универсальное, где например вверху есть выбор справочника из 10 штук (например, как выбор таблицы в table view IBExpert) - тогда конечно, 10 датасетов тут нафиг не уперлись. Так что здравый смысл рулит.

Добавлено: 28 июл 2008, 13:28
KKJ
ок. всем большое спасибо. разобрался.