Форум: "Базы";
Текущий архив: 2006.03.26;
Скачать: [xml.tar.bz2];
ВнизТранзакции MSSQL - работа через BDE Найти похожие ветки
← →
Igor_ © (2006-02-03 10:46) [0]Работаю с MSSQL через BDE.
Из программы рамках транзакции выполняются действия с update и insert в таблицы (T1, T2), которые занимают продолжительное время. В рамках этой же транзакции производится select из таблицы T3 (изменений данных в ней не производится).
Получается ситуация, что во время работы транзакции пользователи в сети, работающие с другими приложениями, которые делают select из T3 не получают данных, пока транзакция не завершится.
Транзакции везде read commited, т.е. по идее приложение делающее select должно свободно получать данные из T3, а получается, что на время транзакции доступ к таблицам просто блокируется.
Подскажите, пожайлуста, как с этим бороться.
← →
Ega23 © (2006-02-03 10:50) [1]А почему-бы не объявлять транзакцию только на Update и Insert? А Select уже вне рамок этой транзакции делать?
ТИпа
Begin Tran
Insert into T1
Update T2
Commit Tran (или Rollback Tran)
Select * from T3
?
← →
Val © (2006-02-03 10:59) [2]>Ega23 © (03.02.06 10:50)
подозреваю, что выборка нужна именно для инсертов и апдейтов. только я разницы не пойму - ну и что что вы вынесете селект из рамок явной транзакции - что изменится-то?
p.s.неужели MS SQL блокирует таблицу на время чтения? странно как-то...
← →
Igor_ © (2006-02-03 11:02) [3]Не получается. Дело в том, что в рамках транзакции проворачивается много данных. И по ходу выполнения, чтобы знать, для чего мне нужно делать update T1 b T2 приходится выбирать select-ом дополнительные данные из T3.
Т.е. схематично все выглядит примерно так:
Begin Tran
for i := 0; .... do begin
Select from T3
Insert into T1
Update T2
end; // for i := 0; ....
Commit Tran (или Rollback Tran)
Можно, конечно, сначала все выбрать и запомнить в переменных программы, а потом у же делать update..
Но здесь вопрос принципиальный. Транзакции read commited, т.е., насколько я понимаю не должны быть видны изменения, которые не подтвердились, но почему доступ вообще блокируется?
← →
Igor_ © (2006-02-03 11:05) [4]
> Val © (03.02.06 10:59)
p.s.неужели MS SQL блокирует таблицу на время чтения? странно как-то...
Вот и я про то же..
← →
Nikolay M. © (2006-02-03 11:09) [5]
> Транзакции везде read commited, т.е. по идее приложение
> делающее select должно свободно получать данные из T3, а
> получается, что на время транзакции доступ к таблицам просто
> блокируется.
Налицо недопонимание механизма блокировок и уровней изоляции.
Про бликировки можно почитать, например, тут:
http://www.sql.ru/articles/mssql/2004/04110303AdvancedLocking.shtml
← →
msguns © (2006-02-03 11:50) [6]>Igor_ © (03.02.06 11:02) [3]
Подобные "хитрые" многоступенчатые изменения в нескольких таблицах БД, которые должны проходить только полностью или не проходить вообще разумнее выполнять не только в контексте единой транзакции, но и на сервере (хп).
← →
Igor_ © (2006-02-03 12:05) [7]
> msguns © (03.02.06 11:50) [6]
Подобные "хитрые" многоступенчатые изменения в нескольких таблицах БД, которые должны проходить только полностью или не проходить вообще разумнее выполнять не только в контексте единой транзакции, но и на сервере (хп).
А перенос в хп поможет решить описанную проблему?
Хотя, перенести в хп вряд ли получится, т.к. в процессе update БД выполняется не просто так q.SQL.Text := "Update..", а в приложении довольно сложная логика и создана куча классов, которые эту логику реализовывают. Если перенести все в хп, то будет очень трудно ее (логику) контролировать и вообще понять..
← →
ЮЮ © (2006-02-03 12:13) [8]
> т.к. в процессе update БД выполняется не просто так q.SQL.
> Text := "Update..",
1) Text := "Update..", всё же лучще сменить на
qUpdate.Params[0].asXXX
...
qUpdate.Params[nn].asXXX
a для qUpdate сделать Prepare
2) Может тогда лучше все сделать на клиенте в кэшированном НД, а потом уже скопом ApplayUpdates?
← →
Val © (2006-02-03 12:28) [9]Знатоки MS SQL, поясните, если несложно, все-таки - почему в данном случае блокируется T3? Я, к сожалению, еще не знаком с данным сервером и информация по ссылке Николая не натолкнула меня на понимание ситуации :( Я вижу только блокирующее чтение - это так?
← →
ЮЮ © (2006-02-03 12:45) [10]Именно из T3? Значит автор где-то задел её на Update (В 17-строке, наверное).
Сейчас проверил. Более того Блокируется SELECT с WHERE Code = <ключ измененной записи>, а если Code другой записи или вообще без Where - то селект не блокируется. (селекты делал из SQL Explorer, блокировку и update - EM)
← →
Val © (2006-02-03 12:53) [11]>[10] ЮЮ © (03.02.06 12:45)
ну это понятно и разумно, спасибо.
← →
msguns © (2006-02-03 13:14) [12]>Val © (03.02.06 12:53) [11]
Принцип блокировок при обработке конкурирующих транзакций можно посмотреть на примере акцеса.
← →
Igor_ © (2006-02-03 14:54) [13]Прошу прощения. Не совсем верно был описана постановка вопроса. Как оказалось Т3 не блокировалась, просто в другом приложении
> Igor_ © (03.02.06 10:46)
> Получается ситуация, что во время работы транзакции пользователи
> в сети, работающие с другими приложениями, которые делают
> select из T3 не получают данных, пока транзакция не завершится.
невзначай, сразу не заметил, еще был select из T1.
В результате всех мучений, пришел к выводу, что нужно будет переделать логику с использованием кешированных изменений. Т.е. сначала делаю select всего, что нужно, принимаю решение нужно ли мне делать update, а потом в короткой транзакции делаю, собственно, update.
← →
Val © (2006-02-03 15:07) [14]в MS SQL нету аналога оракловского select for update? т.е. блокирования нужного набора именно на уровне строк.
← →
msguns © (2006-02-03 15:11) [15]Вообще при клиент-серверном подходе надежнее отделять операции извлечения данных от их изменения. В этом случае механизм "Читаем" - "Даем пользователю изменить данные вне БД" - "Формируем запрос на целостное изменение объектов БД" - "Выполняем запрос" - "Обрабатываем ошибки" - "Обновляем отображаемые данные"
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2006.03.26;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.046 c