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

Модераторы: kdv, CyberMax

Ответить
KKJ
Сообщения: 7
Зарегистрирован: 26 июл 2008, 15:17

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

Сообщение KKJ » 27 июл 2008, 12:58

Здравствуйте.
Пишу многопользовательское приложение с использованием 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;

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

KKJ
Сообщения: 7
Зарегистрирован: 26 июл 2008, 15:17

Сообщение KKJ » 27 июл 2008, 13:03

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

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

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 27 июл 2008, 13:57

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

Attid
Спец
Сообщения: 377
Зарегистрирован: 14 ноя 2006, 09:58

Сообщение Attid » 27 июл 2008, 13:59

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

Attid
Спец
Сообщения: 377
Зарегистрирован: 14 ноя 2006, 09:58

Сообщение Attid » 27 июл 2008, 14:01

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

KKJ
Сообщения: 7
Зарегистрирован: 26 июл 2008, 15:17

Сообщение KKJ » 27 июл 2008, 14:47

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

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

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

т.е. как раз и делаю перевыполнение.
Последний раз редактировалось KKJ 27 июл 2008, 15:04, всего редактировалось 1 раз.

Attid
Спец
Сообщения: 377
Зарегистрирован: 14 ноя 2006, 09:58

Сообщение Attid » 28 июл 2008, 09:27

тебе ответили и дали ссылочку почитать.

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

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

KKJ
Сообщения: 7
Зарегистрирован: 26 июл 2008, 15:17

Сообщение KKJ » 28 июл 2008, 10:05

Attid писал(а):тебе ответили и дали ссылочку почитать.

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

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

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 28 июл 2008, 11:53

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

KKJ
Сообщения: 7
Зарегистрирован: 26 июл 2008, 15:17

Сообщение KKJ » 28 июл 2008, 12:17

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

KKJ
Сообщения: 7
Зарегистрирован: 26 июл 2008, 15:17

Сообщение KKJ » 28 июл 2008, 12:20

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

Attid
Спец
Сообщения: 377
Зарегистрирован: 14 ноя 2006, 09:58

Сообщение Attid » 28 июл 2008, 12:44

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

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 28 июл 2008, 13:14

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

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

KKJ
Сообщения: 7
Зарегистрирован: 26 июл 2008, 15:17

Сообщение KKJ » 28 июл 2008, 13:28

ок. всем большое спасибо. разобрался.

Ответить