![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Блокировка таблицы транзакцией в MSSQL [D7, MSSQL]
lats © (2005-02-07 08:25:00)Начинаю транзакцию. При этом блокируется таблица или даже вся база. Испльзую ADO.
Ega23 (2005-02-10 13:12:00) [1]запись подтверждать менее красиво
Зато более актуально при количестве клиентов > 1.
Serggg (2005-02-10 13:01:00) [2]ну как же. Типа, открыл файл, внес изменения, закрыл файл с сохр. или без. Аналогично и с базюкой. Каждую запись подтверждать менее красиво
Danilka (2005-02-10 11:55:00) [3][34] lats © (10.02.05 11:33)
> Да никого я не жду уже давно все сделал.
маладец. :)
только, некрасиво как-то, все-таки, писать в базу, а по отмене удалять оттуда..
а на счет множественного изменения мастера и его детальных, тут можно попытаться свой кэш сделать на основе датасетов в памяти, например MemTableEh, входящий в дистрибутив EhLib. Но там гемороя будет больше. Однако, я все-таки не понимаю необходимости обязательного множественного изменения мастера.
Ega23 (2005-02-10 11:51:00) [4]через жопу ты сделал. Поверь.
lats (2005-02-10 11:33:00) [5]
> Ну, тогда сиди и жди доброго дядю. который тебе красиво
> сделает. :)
Да никого я не жду уже давно все сделал.
По нажатию "отмена" в мастере удаляется запись которую добавлял, а в детальных все сами удаляются т.к. связанные. Вот и всё. Без транзакций. А как сделать множественную отмену в масере так и не ясно. Хотя можно запоминать какие добавляем и опять же скопом их все удалять. Или даже пошаговое удаление можно реализовать. Мне это правда не нужно.
Danilka (2005-02-10 11:17:00) [6][32] Serggg (10.02.05 10:36)
Хм, а это действительно необходимо? Редактирование/добавление нескольких записей и в мастер и в деталь для них в рамках одного изменения?
Тут гемороя будет больше, с учетом того, что айдишники у мастера автоинкрементные..
Проще перестроить логику работы, чтоб юзерам нормально было когда за раз только одна мастер-запись крячится. :)
Serggg (2005-02-10 10:36:00) [7]Данилка, примерно так же и я пытался сделать, но есть одно жирное НО... В этом случае дважды добавить в мастер-таблицу данные в рамках одной транзакции не получится, так ведь? (иначе заблокируется табличка на МССКЛ). Т.е. отменить ВСЕХ изменений скопом не получится, тока в детальной. :( А еще у меня используется ADOCommand, действия которого в этом случае тоже не откатить :( Хнык.
Danilka (2005-02-10 07:37:00) [8]Да, забыл добавить, в деталь на БефореИнсерт пишется id мастера из параметра, по которому фильтруется (в случае с добавлением новой записи вв мастер, туда пишется -1, соответственно).
И еще, в п.3, п.4 слежует учесть, что сначала меняется состояние на dsInsert, и только потом скроллится на новую запись, соответственно вызывается AfterScroll.
Вобщем, все решаемо, и это не единственный способ, возможно и не самый красивый, незнаю чего вы тему несколько дней мусолите.
Danilka (2005-02-10 00:20:00) [9][29] Desdechado © (09.02.05 18:36)
У него не БДЕ, а АДО, в АДО ApplyUpdates называецца как UpdateBatch.
:))
[25] lats © (09.02.05 14:33)
> но для того и создан Делфи чтобы ручками как можно меньше
> делать
Ну, тогда сиди и жди доброго дядю. который тебе красиво сделает. :)
27] Serggg (09.02.05 15:21)
Тока-шо сделал, пришлось повозиться, но работает. :)
Сделал таким образом:
1. Мастер-таблица просто оптимистическая, детальная уже BatchOptimistic.
2. Связаны мастер/деталь не по-обычному, а ручками, в AfterScroll мастера деталь закрывается, меняется параметр на новый айдишник и снова открывается.
3. На DataSource мастера, на событие OnStateChange вешаем обрабочик, в котором смотрим - если поменялся на dsInsert, то пишем в параметр детали: -1 и переоткрываем ее.
4. У мастера режимах dsInsert и dsEdit запрещаем скроллить.
5. По кнопке "Ок" делаем следующее:
старт транзакции
пост записи-мастеру, если он до этого был в состоянии dsInsert, то забираем сгенеренный айдишник, примерно так:
id := ADOConnection1.Execute('select @@IDENTITY').Fields[0].Value;
далее, пробегаемся по записям детайла и пишем ему айдишник мастера.
UpdateBatch детайлу
коммит.
все работет, без проблем.
Desdechado (2005-02-09 18:36:00) [10]посмотри еще раз Desdechado © (08.02.05 17:31) [22]
там не временные таблицы и тем более не переменные, а нормальный набор данных, изменения в котором до нажатия кнопки хранятся в кэше (его кэше, а не в твоем ручном)
lats (2005-02-09 16:46:00) [11]Вот и я про то-же. Предложили выход - хранить все изменения и дополнения во временных (переменных, таблицах), а потом махом все изменения записывать. Сказали, что примерно так работает фокспра. Много ручной работы. Может есть какой другой выход?
Serggg (2005-02-09 15:21:00) [12]Не, может не очень понятно ситуацию обрисовал, но... Мастер-детальные таблички! Если главная табличка у меня в BatchOptimistic, то первичного ключа до момента UpdateBatch я не имею (т.е. значение полю pk не присваиваивается), соответственно, при вставке записей в дочернюю таблицу я не могу прописать ссылку на первичный ключ строки главной таблицы, к которой относятся детальные строки. Кроме того, выполняются ряд операций по удалению/добавлению блоков данных с использованием ADOCommand... хм... как жить?
lats (2005-02-09 14:33:00) [13]UpdateBatch не подойдет, т.к. добавление записей в дочерние таблицы производится с помощью процедур на сервере.
А во вторых, не лениво. Можно и на асемблере написать, но для того и создан Делфи чтобы ручками как можно меньше делать. Этот вопрос уже много раз обсуждался.
lats (2005-02-09 14:33:00) [14]UpdateBatch не подойдет, т.к. добавление записей в дочерние таблицы производится с помощью процедур на сервере.
А во вторых, не лениво. Можно и на асемблере написать, но для того и создан Делфи чтобы ручками как можно меньше делать. Этот вопрос уже много раз обсуждался.
lats (2005-02-09 14:28:00) [15]UpdateBatch не подойдет, т.к. добавление записей в дочерние таблицы производится с помощью процедур на сервере.
А во вторых, не лениво. Можно и на асемблере написать, но для того и создан Делфи чтобы ручками как можно меньше делать. Этот вопрос уже много раз обсуждался.
Danilka (2005-02-08 20:54:00) [16][21] lats © (08.02.05 16:48)
> Мне это уже предлагали, но в этом случае ручками писать
> много нужно. Автоматизации никакой.
Во-первых, их есть уже, и говорил я про них в самом начале ветки, UpdateBatch для всех наследников TCustomADODataSet, помнишь? Так и не почитал справку?
А во-вторых, даже если чего-то ручками придется делать, и что,
лениво очень? Ну, тогда остается только посидеть, погрустить. :)
Desdechado (2005-02-08 17:31:00) [17]Не в переменных, а в кэшированных датасетах.
А когда придет время (юзер жмет ок), то сбрасываешь кэш в базу в одной короткой транзакции. Для этого есть даже специальные компоненты UpdateSQL для БДЕ или метод beforeupdaterecord в dataprovider.
И, естественно, ApplyUpdates.
см. в справке и примерах в demos
lats (2005-02-08 16:48:00) [18]Т.е. хранить все данные в переменных, а потом их скопом записывать и раскидывать по таблицам? Мне это уже предлагали, но в этом случае ручками писать много нужно. Автоматизации никакой.
Danilka (2005-02-08 16:42:00) [19][19] Serggg (08.02.05 16:02)
> но должны же быть нормальные способы...
Самый нормальный способ тебе уже сказали: все что делает клиент у себя на компе нифига на сервер заносить не надо, пока он не нажмет кнопку ОК. Вот когда нажал ее, тогда открывай транзакцию и пиши на сервак что надо, а если он отмену нажал - тогда ничего не пиши. Чего в этом сложного-то?
Serggg (2005-02-08 16:02:00) [20]а если это не добавление, а изменение? Неее, так конечно тоже можно, но должны же быть нормальные способы... тем более если несколько записей добавлялось в главную? У меня ж сохранение идет в конце сеанса работы (т.е. при сохранении или выходе из окна)