![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Вечная тема - транзакции InterBase. [D6, IB6.x]
Vemer © (2004-01-07 21:34:00)
Здравствуйте.
Пожалуйста помогите разобраться. Прочитал несколько статей и запутался.
Одни источники утверждают, что постоянный CommitRetaining не есть хорошо, в других написано, что если делать в начале .StartTransaction, то CommitRetaining работает как Commit но "без разрыва".
Что ближе к истине? В принципе я могу регулярно делать Commit, но это вроде незачем при втором варианте.
Johnmen (2004-01-12 09:16:00) [1]
>Petr V. Abramov © (12.01.04 03:15) [23]
> Не-а :) Потому что по умолчанию isc_tpb_concurrency стоит,
>isc_tbp_read_commited + isc_tpb_rec_version - и все нормально
А-а...Понятно. Это был тест на телепатические способности...:)
> Ну и что, от этого блокировок нет? :)
Нет. Просто можно их как бы "эмулировать".
>Мнение, конечно, официальное, но из серии "бескорыстного
>несения демократии иракскому народу" :) Ну или я чего-то
>важного не понимаю (:
:))) Я тоже...
jack128 (2004-01-12 09:08:00) [2]
> Petr V. Abramov © (12.01.04 03:15) [23]
Это ошибка терминалогии. IB любую ошибку обнавления дедлоком зовет..
Deniz (2004-01-12 08:32:00) [3]
> Petr V. Abramov © (11.01.04 22:34) [20]
deadlock возникает в другом случае, в Вашем примере транзакция В получит отказ на обновление(raise), а вот пример deadlock"а:
тр1 и тр2 - транзакция 1 и 2 соот-но в режиме wait
тр1: update rec1
тр2: update rec2
тр1: update rec2
тр2: update rec1
Обе транзакции ждут завершения конкурирующих по Commit или Rollback. Вот здесь и будет deadlock.
> jack128 © (11.01.04 19:58) [19]
"Рефреш там есть. И делать его полезно, чтобы увидеть изменения от других клиентов..."
Из этой фразы, причем не совсем полно сформулированной, следует, что проходит Refresh, но не сказано, что Refresh"ится весь набор данных ... я уже писал это:
"... при изменении/добавлении записи некоторые поля могут изменится на сервере, но для нормального просмотра наобходимо только измененную/добавленную запись перечитать ...", именно так и поступает FIBPlus при Refresh"е. В фразе "на сервере" имелось ввиду, что таблица создана с использованием полей, изменяемых сервером. Т.е.
create table ...
upd_date date default NOW,
upd_user varchar(20) default CURRENT_USER
...
upd_date и upd_user просто пример.
Petr V. Abramov (2004-01-12 03:15:00) [4]
> Johnmen © (11.01.04 23:06) [21]
Не-а :) Потому что по умолчанию isc_tpb_concurrency стоит, isc_tbp_read_commited + isc_tpb_rec_version - и все нормально
> т.к. IB версионник...
Ну и что, от этого блокировок нет? :) Мнение, конечно, официальное, но из серии "бескорыстного несения демократии иракскому народу" :) Ну или я чего-то важного не понимаю (:
По-любому, спасибо, что откликнулись :)
Vemer (2004-01-12 01:24:00) [5]
Спасибо за разные мнения.
Вопрос действительно вечным оказался. Вот как сделал в итоге в дополнение к (5). Две транзакции, одна читает неизменные списки, другая читает/пишет изменяемые. Делить на чисто чтение/запись неразумно по-моему (в моем случае) так как после внесения изменений все равно Open/close надо будет делать для некоторых динамических списков(хотя они read-only), вот они и дружно висят на 1-ой (второй).
Johnmen (2004-01-11 23:06:00) [6]
>Petr V. Abramov © (11.01.04 22:34)
Не совсем ясно про блокировки, т.к. IB версионник...
>Вопрос - с какого?
Так ведь первая тр-ия уже изменила запись. А во второй мы этого ещё не видим, т.к. селект "старый"...
А еще лучше почитать про это как обычно на ibase.ru :)
Petr V. Abramov (2004-01-11 22:34:00) [7]
А блокировки CommitRetaining освобождает?
Ситауция:
1.
Транзакция A: select запись
Транзакция B: select запись
2.
Транзакция A: delete запись по where ключ = :параметр
CommitRetaining
3.
Транзакция B: delete запись по where ключ = :параметр
deadlock
Вопрос - с какого?
jack128 (2004-01-11 19:58:00) [8]
Из этой фразы
> Рефреш там есть. И делать его полезно, чтобы увидеть изменения
> от других клиентов...
я сделал другой вывод :-). Что ж, тогда я все еще полон желания купить fib+
Johnmen (2004-01-11 19:55:00) [9]
>jack128 © (11.01.04 19:52)
А я и говорил про одну, текущую, запись в НД.
jack128 (2004-01-11 19:52:00) [10]
> Рефреш там есть. И делать его полезно, чтобы увидеть изменения
> от других клиентов...
К сожелению исходников фибов нету, но имхо такой подход не есть good, если в dataset"e тяжелый запрос. Обновлять ВЕСЬ набор данных - слижком накладно. Refresh"ить нужно только текущую(добавленную) запись
VID (2004-01-11 19:38:00) [11]
Johnmen... и то верно :)
Johnmen (2004-01-11 18:20:00) [12]
>VID © (11.01.04 18:18)
Так я же и говорю, что коммит один раз в конце работы...:)
VID (2004-01-11 18:18:00) [13]
To Johnmen: я знаю, но ведь эту же транзу в этот момент используют датасеты для отображения своих данных, и если я в каком нить читающем запросе, выполню Commint, то во всех датасетах данные пропадут - придётся их всех потом переоткрывать...
Johnmen (2004-01-11 18:10:00) [14]
>VID © (11.01.04 17:59)
Чисто читающую тр-ию достаточно просто коммитить в конце работы программы, один раз.
>jack128 © (11.01.04 12:23)
Рефреш там есть. И делать его полезно, чтобы увидеть изменения от других клиентов...
VID (2004-01-11 17:59:00) [15]
Я например делаю так: Запросы на ПОЛУЧЕНИЕ данных, причём когда получаю множество строк(с последующим проходом по ним) я подтверждаю методом CommitRetaining, потому что эти запросы используют Transaction1, которая настроена как ЧИТАЮЩАЯ транзакция, и в таковой роли используется во всех tpfibdataset.
А запросы на вставку,удаление и изменение записей, я подтверждаю методом Commit, т.к. работа проиходит через Transaction2 которая настроена как ПИШУЩАЯ. И она же используется в качестве пишущей транзакции во всех датасетах.
Если же надо выполнить запрос на ПОЛУЧЕНИЕ данных, когда получена будет одна строка, то я использую Default-транзакцию базы данных - Transaction3 - которая является пищущей и читающей, и подтвержденеи этого запроса выполняю методом CommitRetaining.
jack128 (2004-01-11 12:23:00) [16]
> Попробуйте FIBPlus, хотя и в IBX можно реализовать подобное!
> 2 транзакции: 1 - чтение, 2 - запись. 2-ая транзакция ВСЕГДА
> завершается по COMMIT, причем она(транзакция) очень короткая,
> а после завершения Refresh в первой транзакции. И все.
имхо в фибах не так сделано. Данные, после того как добавлены в базу, просто вставляются в локальный кеш датасета, никаких refresh"tей там нету..
Johnmen (2004-01-09 14:34:00) [17]
Весьма полезно, особенно если с Чубайсом не на "ты", выставить базе ForcedWrites в Enable...
Vemer (2004-01-09 12:38:00) [18]
Прога локальная. Yaffil Personal. все данные вытягиваються маленькими порциями. И с электричеством не очень (UPS может будет). Поэтому важные изменения лучше Коммитить.
Deniz (2004-01-09 12:31:00) [19]
> div (09.01.04 10:07) [7]
Вообще-то на сервер нужно посылать только те данные, которые менялись, и " поднять данные с сервака..." звучит немного, хм, неправильно. Дело в том, что при изменении/добавлении записи некоторые поля могут изменится на сервере, но для нормального просмотра наобходимо только измененную/добавленную запись перечитать. И к тому же "тянуть" с сервера ВСЕ записи ... об этом уже говорилось не раз, ну не может(физически) пользователь работать с большим(зависит от конкретной задачи 10..100) кол-вом записей :)!
div (2004-01-09 10:07:00) [20]
Методы CommitRetaining / RollbackRetaining значительго облегчают жизнь нашему брату ))) да и к тому же если использовать Commit / Rollback то нагрузка на сеть нефиговая будет (если конечно у тебя не 100 запией ))). Подумай: неважно делаешь ты Commit или Rollback, следующий твой шаг - поднять данные с сервака... все... даже те которые ты не изменял...
А если совместить CommitRetaining с режимом кэшированных апдэйтов (извиняюсь за косноязычность))) нагрузка на сетку будет минимальной, а это сразу повышается производительность.
Хотя все конечно зависит от специфики посталенной задачи.