|
|
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
to Senin Viktor не мог бы ты пояснить - что именно ты понял я точно понял только одно - блокировка при открытой транзакции существует на отрезке времени между update и commit - собственно том отрезке, когда непосредственно в базе журналируются изменения состояний таблиц. То есть, это БЫЛО бы проблемой отложенного commit-a, если бы человек не утверждал, что база освобождается только при закрытии приложения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 18:16 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
2Victosha >> я точно понял только одно - блокировка при открытой транзакции существует на отрезке времени между update и commit - собственно том отрезке, когда непосредственно в базе журналируются изменения состояний таблиц. Вот имеено - на этом отрезке мы все и пытались отредактирвоать данные - BeginTran - Update - попытка редактировать заблокированную таблицу - CommitTran. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 20:29 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Знаете, я немного погорячился сказав что таблица разблокируется только после завершения программы, конечно я имел в виду завершение транзакции. Senin Viktor Я специально не проверял, но все же мне кажется блокируются не все таблицы, а именно тех в которых был вызван Update. У меня в базе таблиц штук 100, а юзеры начинают бегать только с воплями что клиенты не заводятся или их заказы, т.е. как раз в те таблицы в которые я закачиваю, в остальном вроде тихо, иначе бы такой вой поднялся! Victosha Код блокирует, говорю же тебе, остановить сразу после Update не доходя до CommitTran и проверь. Senin Viktor ведь это подтвердил. И что за мания следователя? Ничего я не утаиваю! :) Я уже привел отдельный конкретный экспирементальный образец базы и приложения, где всего один процесс, одна транзакция и один рекордсет, никаких контролов более! Я все же не вижу логики зачем Jet понадобилось блокировать таблицу после добавления записи. Люди, черт с ними с рекордсетами, если уж так все запущено. Давайте разберемся как провернуть этот фокус с @@Identity. Первый раз слышу что такое можно не в хранимой процедуре, а в базе Access. Надеюсь что мне повезло, потому что база именно Access 2000. Как будет выглядеть код? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 21:13 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Ну чтож, можно считать, открытие состоялось. Сие великое поведение есть результат комбинации именно adUseClient и дефолтного adXactReadCommitted уровня изоляции. To Senin Viktor – вот как раз этого – что между update и Commit у автора вопроса что-то происходит я упорно и не видел. To Pantalone - буду бурчать - терпи. Ты шибко-то не серчай. Никакой тайной мысли тебя обижать не было, а было явное стремление выудить детали происходящего. До опыта кажется, что это в первую очередь твой интерес. В опыте правда почудилось, что ты просто посмеяться над людями задумал, как та девочка, что бросает свою игрушку в лужу, а потом показывает пальцем на мальчика, который ее вернул, смеясь над тем, что он грязный. (копирайт от Берна). А, оказывается, я сам во всем этом. Можно было бы и раньше ситуацию опознать – читая назад видно – намеки разбросаны. Ну вот не знал я такой мудрой в своей конкретности детали – НЕ ЗНАЛ. И представить себе, что именно в этом углу искать надо – не мог, по культурным своим заборам. Диагноз-то все-таки поставлен, что и есть медалью на грудях и залогом длинной жизни. А то, что дохтур злобный и глупый – как видишь, это не смертельно. Оно же ведь - все знать можно, только вне пространства находясь. ЗЫ получается длинно - потому будет двумя постами ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.03.2004, 01:41 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
теперь по существу исходного вопроса. Понижение уроня блокировки до adXactReadUncommitted при сохранении adUseClient решает проблему блокировки. При adUseServer блокировки не возникает вообще, но урвень изоляции остается фактически adXactReadCommitted, независимо от того, что говоришь соединению - это как раз то, о чем мечтает и чего не хочет автор вопроса (потому что ему нужен рекордкаунт). ЗЫ Была мысля разродится примерами с пояснениями, но что - то загрустилось - видно пора в холодильник ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.03.2004, 01:50 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Victosha При adUseServer блокировки не возникает вообще Попробуй еще раз. При количестве записей в таблице штук 10. Понижение уроня блокировки до adXactReadUncommitted при сохранении adUseClient решает проблему блокировки. adXactReadUncommitted это где, это кто? Снова появилась надежда разобраться с рекордсетами, уж больно неохота на Insert переходить, лень - двигатель прогесса как известно :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.03.2004, 09:01 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
2Victosha Понижение уроня блокировки до adXactReadUncommitted при сохранении adUseClient решает проблему блокировки. При adUseServer блокировки не возникает вообще Приведи свой код (например для Борея) в котром не возникает блокировок (кстати таблица Заказы тоже блокируется из-зы DRI) А вотмой код (блокировки есть): Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.03.2004, 09:26 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Да, робяты, при adXactReadUncommitted та же хрень. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.03.2004, 09:44 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Видимо труба. Давайте с @@Identity попробуем, хотя у меня и Access 2000 но в хелпе по этому вопросу шаром покати. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.03.2004, 11:11 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Кстати вот тут интересный примерчик на тему получения ID добавленной записи. Интересный потому что непонятно зачем там для этого используется bookmark, absolutePosition и Requery? Когда ID новой записи и без этого сразу видно после Update ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.03.2004, 11:49 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Собственно @@Identity для Jet OLE DB Provider Version 4.0 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.03.2004, 11:51 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Все понятно, там выцарапывается ID при добавлении записи в SQL Server. Для Access это все лишнее, ID сразу виден. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.03.2004, 11:53 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Это если через рекордсет добавлять. А если запросом то нужно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.03.2004, 12:03 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Шеф, все пропало!!! (с) Б. Рука Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. Microsoft Knowledge Base Article - 232144 When you submit the new row to the Jet provider by calling Update or UpdateBatch (depending on your choice of LockType), the ADO cursor engine generates an INSERT INTO query to create the new row in the table. If the recordset contains an auto-increment field, ADO will also generate a SELECT @@Identity query to retrieve the value generated for that auto-increment field. Остается только разрыдаться на плече Билла ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.03.2004, 12:22 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Я убью его!!! (с) Б. Рука :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.03.2004, 12:57 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Рыдать не надо - Pavel выше уже сказал - транзакции должны быть короткими - ты сразу после Execute делай CommitTran и затемполучай свой идентити и не парся. З.Ы. По возможности - ни каких циклов по рекордсетам (вообще от рекодсетов отказаться надо - в пользу SQL-языка), по возможности активно использовать временные таблицы, в которые заливать данные и уже в транзакции, одним оператором, быстро выполнять обновление. Способов много, еще их больше на MS SQL. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.03.2004, 12:58 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Senin Viktor сразу после Execute делай CommitTran и затемполучай свой идентити и не парся. А как я откат буду делать всего что уже назаливал в базу к моменту ошибки или отмены юзером??? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.03.2004, 13:24 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
А как я откат буду делать всего что уже назаливал в базу к моменту ошибки или отмены юзером??? Есть такая легенда про юзера который начал редактировать таблицу (есно, она заблокировалась) и ... ушел в отпуск - так вот если не изменишь подход - то эта легенда станет явью. Для тебя. З.Ы. Не зная логики работы твоей проги (и вообще чегонужно) - трудно давать какие-либо советы. Только общие. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.03.2004, 13:47 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Это не легенда, а пример как бывает когда юзер редактирует запис и не окончив это радостно топает на обед. Заблокирована там вроде оказывается всего одна запись. Да ладно, это все шутки, то что логику менять придется это ясен пень. Жаль что мельницу не победили. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.03.2004, 13:53 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
К счастью для меня это стало легендой. А когда-то было кошмаром, и имя кошмару - Paradox. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.03.2004, 15:26 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Код поменял, теперь все делается за секунды, но находятся несчастные юзеры, которые умудряются и за эти секунды со мной пересечься. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.03.2004, 10:11 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Секунд ы - это много, хотя фиг тебя знает - м.б. ты ядерный взрыв моделируешь :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.03.2004, 10:22 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
приношу извинения за вчерашнее молчание - несколько ежом по сковордке день оказался, "ОТКРЫТИЕ" придется ЗАКРЫТЬ (с двойным изумлением) постараюсь вечером подробный отчет ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.03.2004, 10:40 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Отчет об истории с «открытием». Как могу, подробно. Началось с того, что решил нарисовать пару «классических учебных» примеров по работе с транзакциями (как надо и нет) для Pantalone, на основе той структуры, которую он привел. Хотел продемонстрировать, в том числе, то, что не знаю, кто еще, кроме Jet (из широко обсуждаемых «промышленных» СУБД) умеет – поддержку вложенных транзакций и особенности их применения. Изложу в сокращенном варианте кода с комментарием, применительно к базе Борей, как просил Senin Viktor Еще одно изменение – из набора Сабов они преобразованы в одну макаронину. Кусок, вызвавший скоропалительные заявления, помечен как ЗАКРЫТИЕ ОТКРЫТИЯ. Привожу «рабочий» до места закрытия открытия кусок для однократного запуска с точностью до пути к базе. ПОСТАВИТЬ ТОЧКУ ОСТАНОВА перед строкой, помеченной как ИЗУМИТЕЛЬНОЕ МЕСТО Option Compare Database Option Explicit Sub test1() Dim cnN1 As ADODB.Connection Dim tRec As Recordset Dim sqlStr As String Dim sCode As String Set cnN1 = New ADODB.Connection With cnN1 'используется "дефолтная" system.mdw .Provider = "Microsoft.Jet.OLEDB.4.0" .Properties("Jet OLEDB:Database Locking Mode") = 1 .Mode = adModeShareDenyNone .CursorLocation = adUseClient 'adUseServer 'adUseClient 'какой курсор - не важно до места отказа от "открытия" .IsolationLevel = adXactReadUncommitted ' adXactBrowse,adXactCursorStability 'adXactReadUncommitted 'уровень изоляции - не важно до места отказа от "открытия" .Mode = adModeShareDenyNone .Properties("Data Source") = "D:\MSOFFICE2K\Office\Samples\Борей.mdb" .Open End With sqlStr = "SELECT [КодКлиента],Название FROM Клиенты Where 0=1" 'запрос возвращает пустое множество записей, используется только для добавления Set tRec = New ADODB.Recordset cnN1.BeginTrans tRec.Open sqlStr, cnN1, adOpenKeyset, adLockOptimistic, adCmdText cnN1.CommitTrans ' приблизительно так писали "раньше" в стремлении освободить быстрее принудительно блокировки выборки 'СКРИПТ-1 ' открываем транзакцию записи cnN1.BeginTrans sCode = "_" & String(4, "0") ' With tRec 'первое добавление .AddNew ![КодКлиента] = sCode ![Название] = "ddddd" .Update 'здесь начинается специально помеченное место которое блокирует "другие" транзакции 'в той же транзакции записи добавляются 'второе добавление в той же транзакции sCode = "_" & String(4, "1") ' .AddNew ![КодКлиента] = sCode ![Название] = "ddddd" .Update End With cnN1.CommitTrans 'конец первой транзакции - добавлено две записи '---------------------------- 'покажем работу вложенных транзакций 'счет транзакциям начнем с единицы ' открываем 1ю транзакцию записи 'СКРИПТ-2 Dim badCode As String cnN1.BeginTrans sCode = "_" & String(4, "2") ' With tRec 'первое добавление .AddNew ![КодКлиента] = sCode ![Название] = "ddddd" .Update 'второе добавление в той же транзакции sCode = "_" & String(4, "3") .AddNew ![КодКлиента] = sCode ![Название] = "ddddd" .Update 'третье добавление в какой транзакции? sCode = "_" & String(4, "4") 'ТОЧКА ОТКАТА .AddNew ' кажется, что открыли запись в первой транзакции ![КодКлиента] = sCode ' открываем вложенную (вторую) транзакцию - в "других" движках как правило это просто увеличивает trancount cnN1.BeginTrans ![Название] = "ddddd" ' а это в какой транзакции пишем? 'типа читаем ID текущей записи (как будто @@IDENTITY восстанавливаем ) badCode = ![КодКлиента] .Update sCode = "_" & String(4, "5") .AddNew ![КодКлиента] = sCode ![Название] = "ddddd" .Update 'точка принятия решения по поводу вложенной транзакции, если все хорошо, то будет Коммит 'одако мы решили, что все плохо и откатываем вложенную транзакцию cnN1.RollbackTrans 'откат произвелся до 'ТОЧКА ОТКАТА ' то есть потеряны будут ОБА кода и _4444 и _5555, таким образом, запись _4444 оказалась принадлежащей вложенной транзакции 'внешняя транзакция осталась не закрытой, продолжаем в ней писать sCode = "_" & String(4, "6") .AddNew ![КодКлиента] = sCode ![Название] = "ddddd_" & badCode ' ТОНКОЕ МЕСТО .Update End With cnN1.CommitTrans 'конец СКРИПТ-2 'ОБСУЖДЕНИЕ ' в результате СКРИПТ-2 будут добавлены коды _2222, _3333, _6666 'тонкость ТОНКОГО МЕСТА заключается в том, что оно имитирует информационную взаимосвязь между '_6666 и уже НЕСУЩЕСТВУЮЩЕЙ _4444. То есть, если, например, представить, что T-SQL (от SQL Server), умеет 'поддерживать вложенные транзакции и весь скрипт-2 написан на таком гипотетическом T-SQL, то в этом месте 'для него возникала бы проблема каскадного rollback-а. Он должен был бы решить, 'откатывать _6666 не взирая на последующий Commit или нет, и, скорее всего, он должен был бы откатить. 'Может поэтому он ЭТОГО (реально поддерживать вложенность транзакций) и не умеет. 'Jet же работает честно в рамках богатства своего исполнителя скриптов по работе с базой, ограниченного рамками исполнения одного запроса. 'фактическая ответственность за информационную целостность оказвается разпределена между Jet и VBA, 'иными словами лежит на программисте. О чем почему-то хочется отдельно сообщить. 'ЗАКРЫТИЕ ОТКРЫТИЯ 'изначально планировалось показать влияние уровня изоляции на "видимость" записей ' в разных соединениях. Код был написан в несколько однотипных сабов с вызовом одного дочернего. 'в родительских задавались свойства соединения. 'к базе из одной таблицы, "по Pantalone", без индексов и ключей. Код повел себя "открытым" способом (с adUseServer). 'под это есть зуб и отложенная база, на которой, как ожидается, он должен отработать по крайней мере еще один раз. 'прочитав просьбу показать коды и не имея их под рукой на рабочем компе просто воспроизвел для борея - не идет. 'получив базу из дома по почте результат поимел следующий - нижеприводимый код сработал строго один раз ' после чего база стала "блокироваться" 'размер ~ 130 кб, ~30 записей. 'записи удалил, сжал базу, размер остался 130 кб, поведение не воспроизвелось, - база блокируется. 'Таким образом, "открытие" закрывается с извинениями и непонимаем всего происходящего. 'СКРИПТ-3 Dim cNN2 As ADODB.Connection 'второе соединение Dim tRec2 As ADODB.Recordset ' второй рекордсет Set cNN2 = New ADODB.Connection Set tRec2 = New ADODB.Recordset With cNN2 .Provider = "Microsoft.Jet.OLEDB.4.0" ' .Properties("Jet OLEDB:Database Locking Mode") = 1 - определяется первым соединением .Mode = adModeShareDenyNone .CursorLocation = adUseClient 'adUseServer 'adUseClient .IsolationLevel = adXactReadUncommitted ' adXactBrowse 'adXactCursorStability 'adXactReadUncommitted 'adXactBrowse -типа для демонстрации утверждения о том, что то, что в транзакции - другим не видно. .Mode = adModeShareDenyNone .Properties("Data Source") = "D:\MSOFFICE2K\Office\Samples\Борей.mdb" .Open End With cnN1.BeginTrans ' транзакция на первом коннекте sCode = "_" & String(4, "7") ' With tRec 'первое добавление на первом соединении .AddNew ![КодКлиента] = sCode ![Название] = "ddddd_7777" .Update End With '---------------------------------------- 'открываем второй рекордсет на втором соединении sqlStr = "SELECT [КодКлиента],Название FROM Клиенты " 'запрос возвращает "все" множество записей cNN2.BeginTrans tRec2.Open sqlStr, cNN2, adOpenKeyset, adLockOptimistic, adCmdText cNN2.CommitTrans 'и проверяем, что мы в нем видим 'ТОЖЕ закрытое и очень странное место - о нем говорилось в "открытии" tRec2.MoveFirst Debug.Print tRec2.RecordCount Do While Not tRec2.EOF If tRec2.Fields![КодКлиента].Value Like "_*" Then Debug.Print tRec2.Fields![КодКлиента].Value, tRec2.Fields![Название] End If tRec2.MoveNext Loop Debug.Print "!" 'ИЗУМИТЕЛЬНОЕ МЕСТО 'первое добавление на втором коннекте cNN2.BeginTrans 'транзакция на втором коннекте sCode = "_" & String(4, "8") ' With tRec2 .AddNew ![КодКлиента] = sCode ![Название] = "ddddd_8888" .Update 'ВОТ СОБСТВЕННО ИЗУМЛЕНИЕ, место моего обмана End With cNN2.CommitTrans 'закрываем транзакцию на втором коннекте cnN1.CommitTrans ' закрываем транзакцию на первом конекте. '---------------------------- tRec2.Close Set tRec2 = Nothing cNN2.Close Set cNN2 = Nothing '---------------------------- tRec.Close Set tRec = Nothing cnN1.Close Set cnN1 = Nothing End Sub 'вот как будто и вся история ' ничего хорошего в ней нет '((( 'А выписывать ее оказалось дольше ожидаемого. '((( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.03.2004, 04:48 |
|
||
|
|

start [/forum/topic.php?fid=45&msg=32456678&tid=1675750]: |
0ms |
get settings: |
11ms |
get forum list: |
17ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
190ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
76ms |
get tp. blocked users: |
2ms |
| others: | 243ms |
| total: | 560ms |

| 0 / 0 |
