Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2005.09.18;
Скачать: [xml.tar.bz2];

Вниз

Транзакции в Ado   Найти похожие ветки 

 
Максим   (2005-08-03 22:02) [0]

Добрый день всем!
Использую ADO для работы с MSSql Server. Начинаю транзакцию (Conn.BeginTransaction), всталяю запись в таблицу (pk - автоинкремент). Делаю Post. После чего таблица блокируется полностью до зав ершения транзакции )нелбзя дпже курсор по ней открыть). Как этого избежать?

Спасиобо


 
ЮЮ ©   (2005-08-04 06:27) [1]

Зачем нужна транзакция для вставки одной записи?


 
Виталий Панасенко   (2005-08-04 09:08) [2]

Вот-вот.. Это прелести блокировочника... Там вроди можно блокировку на страницы ставить, а не на всю таблицу...
> ЮЮ ©   (04.08.05 06:27) [1]
> Зачем нужна транзакция для вставки одной записи?

А может, что в триггере обрабатывается.. Например, остаток меняется и должен быть не меньше 0..


 
ЮЮ ©   (2005-08-04 09:16) [3]

>А может, что в триггере обрабатывается.. Например, остаток меняется и должен быть не меньше 0..

Я имею ввиду открытая транзакция. Запрос на вставку, естественно, пойдет после Post, и в триггере что нужно, то и изменится, а зачем транзакция остается открытой?


 
Nikolay M. ©   (2005-08-04 10:04) [4]


> Как этого избежать?

По сабжу: можно обойти на блокировку, например, читая UNCOMMITTED-данные (SELECT * FROM tab (NOLOCK)), но т.о. можно прочитать фантомные записи.
А вообще тема бредовая: для одной операции вставки (хоть одной записи, хоть десяти) явная транзакция не нужна. Точнее, она может быть нужна для искусственного создания описанной ситуации: не дать другим читать таблицу до тех пор, пока не будет снята транзакция. Вот только процент случаев, когда это нужно, ничтожно мал.


 
Максим   (2005-08-04 21:59) [5]

Друзья! Почему все вдруг решили, что мне нужна транзакция ради одной записи? Просто вставка записи это способ получения pk для таблицы с автоинкрементами. Далее идет серия операций по связанным датасетам и ситуация эта сполне реальная. Всякие флажки типа ReadUncommited я уже перепробовал.
Жаль, что никто из специалистов так и не смог дать ответа на конкретно поставленный вопрос.


 
DiamondShark ©   (2005-08-04 22:23) [6]

Это называется конкретно поставленный?


 
sniknik ©   (2005-08-05 08:41) [7]

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

по вопросу. у тебя ошибка в 17 строке.
возможно по причине транзакций (Conn.BeginTransaction) на клиенте, на сервере все замечательно работает.
к примеру
1я команда предварительная
CREATE TABLE Table1 (ID INT IDENTITY(1, 1) PRIMARY KEY, Name VarChar(30), Pole INT)

основная. пакет.
BEGIN TRANSACTION
INSERT INTO Table1 (Name,Pole) VALUES ("Test" , 1)
SELECT * FROM Table1 WHERE ID IN (SELECT Max(ID) FROM Table1)
или
SELECT * FROM Table1 WHERE ID IN (SELECT @@IDENTITY FROM Table1)
ROLLBACK TRANSACTION

и записывает и получает автоинкремент/всю запись и откатывает.
(MSSQL 2005 настройки стандартные, еше ничего не менял)


 
Nikolay M. ©   (2005-08-05 10:01) [8]


> Максим   (04.08.05 21:59) [5]

А ты перечитай [0] и подумай, почему все решили именно так и попробуй найти у себя конкретно поставленный вопрос. Если бы вопрос был "как получить автоинкрементный ID после вставки", соответственно и ответы были бы другими.
Один из правильных ответов - в [17]: SELECT @@IDENTITY. Или SELECT SCOPE_IDENTITY().
Так что учись задавать действительно конкретно поставленные вопросы.


> SELECT Max(ID) FROM Table1

Ненадежно. Даже при наличии транзакции.


 
sniknik ©   (2005-08-05 10:39) [9]

> Ненадежно. Даже при наличии транзакции.
так пример ведь. что даже при чтении тока что созданного инкремента с таблици запись читается.
а так да, глупо.
> или
> SELECT * FROM Table1 WHERE ID IN (SELECT @@IDENTITY FROM Table1)
будет лучше.


 
Nikolay M. ©   (2005-08-05 10:59) [10]


> sniknik ©   (05.08.05 10:39) [9]

:)
Тогда так и пиши: демонстрация селекта. А то ведь кто-то сделает, а потом граблями получит :)
Только зачем подзапросом тянуть @@IDENTITY в количестве, равном числу записей в Table1 - непонятно, а не просто WHERE ID = @@IDENTITY.


 
sniknik ©   (2005-08-05 11:17) [11]

> Только зачем подзапросом тянуть @@IDENTITY в количестве ...
так пример ведь! ;о)) ... не, на самом деле были мысли что ктонибудь именно так и поймет (про Max(ID)), вот и дал "или" более "правильное" но не до конца т.к. получил это копированием предыдушего и заменой на переменную... не подумал в общем.
хотя... можно ведь и DISTINCT поставить ;о)) для достижения еще большей абсурдности, зато будет один и в этом.


 
Nikolay M. ©   (2005-08-05 11:41) [12]


> sniknik ©   (05.08.05 11:17) [11]

Извращенец :)


 
Максим   (2005-08-06 09:38) [13]

Большое спасибо! Вы научили меня получать вновь pk вновь созданной записи (хотя я его вроде и так получал...). Но таблица -то лочиться при insert - вот в чем проблема.
Я придумал ,как сделать вопрос максимально понятным: Есть датасет , есть привязанный к нему грид, который можно редактировать. При открытие формы, необходимо, что бы все изменения сделанный в датасетах можно было как откатить, так и сохранить (в том числе и вставки). После первой же вставки SQl server лочит записи в таблице (вставленные). Единственныt вариантs select, который работает - с указанием with (NOLOCK) или with (READPAST) - приемлем только второй. Есть ли иной выход, кроме как добавлять данное указание ко всем существующим запросам?


 
DiamondShark ©   (2005-08-06 11:44) [14]

Во-первых, за открытие транзакции на время интерактивной работы пользователя руки отрывать. Ржавыми клещами.

Во-вторых, вопрос-таки вовсе не максимально понятный. Второй запрос выполняется в том же connection, или в другом?


 
sniknik ©   (2005-08-06 11:55) [15]

> Я придумал ,как сделать вопрос максимально понятным:
неправильно придумал, все одно непонятно. думай в сторону примера на основе исходногоу кода. так чтобы при желании можно было воссоздать ситуацию (если когото заинтересует), тока не вали сюда все, выдели необходимый минимум...

> После первой же вставки SQl server лочит записи в таблице (вставленные).
приведенный пример как раз показывает что в пределах одной транзакции он этого не делает.
возможно ты пытаешся чтото делать из другого подключения...

> Есть ли иной выход, кроме как добавлять данное указание ко всем существующим запросам?
конечно. можно поменять логику программы, или тоже самое сделать по другому. (не очень понятно что, но уверен можно по другому)
так например чтобы изменения "можно было как откатить, так и сохранить" можно использовать режим ltBatchOptimistic, получится тоже самое (нажал "применить" применилось, не нажал откатилось, вернее, даже и не начало записываться)
а тразакцию открывать надо только для записи связанных данных, тех которые друг без друга безсмысленны, причем на максимально возможное короткое время. не так как у тебя (как понял из "конкретных вопросов" ;о)) для реализации откатов того что человек редактирует в гриде (час, два?), это неправильно в принципе.


 
Nikolay M. ©   (2005-08-06 12:33) [16]


> > После первой же вставки SQl server лочит записи в таблице
> (вставленные).
> приведенный пример как раз показывает что в пределах одной
> транзакции он этого не делает.
> возможно ты пытаешся чтото делать из другого подключения...

Кажется, до меня дошел "конкретный вопрос"... Он открывает транзакцию при первом изменении данных в гриде и оставляет ее открытой. Аналог отвязного датасета, что-ли, реализует? Мдя..


> Максим

TClientDataSet для этого, в частности, существует. Наизменял десяток записей, нажал "Применить" - они все отправились на сервер, нажал "Отменить" - откатились. И никаких долговременных транзакций.


 
Polevi ©   (2005-08-07 09:08) [17]

>Nikolay M. ©   (06.08.05 12:33) [16]
>Он открывает транзакцию при первом изменении данных в гриде и оставляет ее открытой

угу, вася открыл документ на редактирование и пошел обедать
все остальные пользователи тоже пошли обедать



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2005.09.18;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.013 c
3-1123079751
Гость22
2005-08-03 18:35
2005.09.18
Как в Database Desktop убрать ненужное поле таблицы Paradox?


3-1123491610
Rentgen
2005-08-08 13:00
2005.09.18
Как пробежаться по выделеным записям в Table?


14-1124261289
Lexer
2005-08-17 10:48
2005.09.18
Посоветуйте стиральную машину


14-1124451327
cyborg
2005-08-19 15:35
2005.09.18
Нужно ли переустанавливать ForceWare?


14-1124357324
juu
2005-08-18 13:28
2005.09.18
у ICQ снова проблемы ?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский