|
|
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. После .Update таблица становится недоступна для изменений другим пользоателем, даже после rst.close и Set rst = Nothing Только когда из программый выйдешь то все ок. Конекшн используется такой: cnnAccess.CursorLocation = adUseClient cnnAccess.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=\\Dom\D\Data\lab.mdb;" Все добавления делаются в транзакции, так что не понятно зачем блокируется таблица целиком? Ведь добавляемую в транзакции запись не видно, ее никто не изменит. Как отключить блокировку? Если поставить adopenKeyset - не помогает. Хелп!!! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.03.2004, 11:27 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
поставь в AccessConnection.Mode=16 - ljk;yj dsktxbnm ndj. ,tle Прим1 Код: plaintext Код: plaintext Прим2 - если тебе не нужно работать с отстоединенными рекордсетами И не нужен RecordCount- не используй фвГыуСдшуте - кроме доп. перегрузки на память и некоторого замедления - другой пользы не получишь. используй adUseClient ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.03.2004, 12:41 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
в смысле - поставь в AccessConnection.Mode=16 - должно вылечить твою беду ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.03.2004, 12:42 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
авторне используй фвГыуСдшуте Какой хароший савет, суший! Моя тожи всигда думаль, шта нинада исползувать "фвГыуСдшуте", тока боялась сказать штоб за фуфло ни сойти. Тыж мою мысль своими славами изложил тут прям в Ынтернете. спасиба! ЗЫ Просто не мог хоть как-то не отметиться в топике у автора с таким ником ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.03.2004, 13:20 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
To Лифчик будем считать, что познакомились. -) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.03.2004, 13:25 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
а совет был про adUseServer - в смысле его используй. PS пальчы жмакают быстрее, чем глазки смотрют. Правда севодни они и смотрют плохо с утра. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.03.2004, 13:30 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Народ, я забыл сказать что все эти операции я делаю из VB клиента. Т.е. есть прога на VB из которой идет обращение в базу Access 2000. Victosha AccessConnection.Mode=16 это применимо если работать с ADO в Access? А как с VB быть? Транзакции там есть, просто не стал их описывать, банальные .BeginTrans .CommitTrans авторВедь добавляемую в транзакции запись не видно, ее никто не изменит это как бы не совсем верно, если не сказать - совсем неверно. Это еще почему? авторфвГыуСдшуте Я весь пол вытер пока ржал )))) Лифчик Ты бы помог бы лучше, чем истерику тут разводить :) adUseServer использовать не могу, мне нужен RecordCount, но разве из-за adUseServer у меня таблицы блокируются? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.03.2004, 14:48 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
это глазки - они ведели, что человекк плакал, а пальцы жмакают по памяти. имелось ввиду следующее cnnAccess.CursorLocation = adUseClient cnnAccess.Mode=16 ' ЭТО НЕ ПРО АКЦЕСС, ЭТО ПРО ADO.CONNECTION cnnAccess.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=\\Dom\D\Data\lab.mdb;" вообще история плохо смотрится - нет ли там часом контрола, который Bound-ed к той же записи и "одновременно" с кодом редактирует ее? ЗЫ выкладывать часть (вероятно ошибочного) кода не вполне честно вообще, а уж ежели ты ЯВНО транзакции попользовал и скрыл это от населения, то это похоже примерно вот на что. "Мне поставили 2 за сочинение, все что, красным БЫЛО ПОМЕЧЕНО, я вытер - найдите у меня ошибки". зы2 про adUseServer - исключительно из совета экономить ресурсы (комуктера) зы3 про то, кто и что видит "в транзакциях", тема совсем отдельная. Прямо ответом является то, что это определяется заказанным Isolation Level-om. а он в руках (твоих). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.03.2004, 15:03 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Код: plaintext ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.03.2004, 15:05 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
есть такое параметер у ADODB.Connection "Jet OLEDB:Database Locking Mode" Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.03.2004, 15:41 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Victosha Можно расписать слегка что есть cnnAccess.Mode=16? Насчет транзикций, по умолчанию-то их не один юзер не видит ,в смысле добавляемые в транзакции записи, прально? Senin Viktor Т.е. по умолчанию Page-level Locking стоит? А код я не могу полный привести, весь модуль что ли сюда забабахивать? Основное выглядит так: Код: 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. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. Самое интересное: попробовал испытать на тестовой базе. Создал базу, создал в ней простую таблицу, запустил код - после Update если попытаться редактировать любую запись в таблице Access выдает: <Обновление невозможно; установлена блокировка> Меняю adOpenDynamic на adOpenKeyset - ура! после Update записи даются редактировать. Пошел заменил в основной базе adOpenDynamic на adOpenKeyset, вроде срабатывает, записи редактируемые после Update, но через некоторое время работы они опять блокируются и каким образом не пойму. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 09:58 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Блин, правки сообщений тут нет что ли? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 10:00 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Ребят, обнаружилось что все же блокируется не вся таблица, а некоторая ее часть (называется страница?). Уже лучше. Как бы добиться блокировки только одной записи. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 10:48 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Перейти на MSDE. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 12:07 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
2Pavel Перейти на MSDE. Ну и там страничная блокировка есть :) 2Pantalone Ты пробовла мой совет про Row locking? Как бы добиться блокировки только одной записи. в общем - это решает оптимизатор - какой способ блокировки ему выгодней - такой и будет использоваться, что бы ты не написал и не сделал. З.Ы. А индексы (ПримариКей и пр.) есть в Products ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 12:12 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
16 - это adModeShareDenyNone - открытие базы в режиме "совместного использования". про открытие в режиме страничной блокировки или на уровне записи написал Senin Viktor все еще неочивидно, что приведенного кода достаточно, но кое-что вытанцовывается: на мой взгляд,проблема именно в транзакциях. Детально ОБЪЯСНИТЬ не сумею, а на уроне советов, представляется, что есть 3 пути обхода 1) Выкинуть наружные транзакционные скобки 2) изменить логику, использующую рекордсет - Настоятельно рекомендую открывать рекордсет до явного объявления транзакции по ДОБАВЛЕНИЮ (прим - открывать рекордсет имеешь право в собственных транзакционных скобках, так так для версий до 97 это повышало сетевую юзабельность, освобождая лишние блокировки, накладываемые при отборе записей - потом стали говорить "НЕ НАДО- мол "встроенные транзакции в этом месте хорошо работают"") и закрывать его (рекордсет) ПОСЛЕ Коммита транзакции по добавлению. 3) отказаться от использования рекордсета и перейти к коду типа dim Result as Long dim sqlStr as String sqlStr = "INSERT INTO Products (Id_Customer,Name) VALUES ( " & _ Cstr (Id_Customer) & "," & fmtStr(Name) & ")" With cnnAccess .BeginTrans .ExecInsert SqlStr, Result, adExecuteNoRecords .Commit End With '--------------- Function FmtStr(ByVal vString As String) As String FmtStr = Replace(vString, "'", "''") FmtStr = "'" & FmtStr & "'" End Function ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 12:18 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
cnnAccess.Mode=16 не помогло. cnnAccess.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=C:\biblio.mdb;Jet OLEDB:Database Locking Mode=1" Тоже. Что такое авторнаружные транзакционные скобки и как их выкинуть? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 12:39 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
вкралась очепятка имелось ввиду .Execute SqlStr, Result, adExecuteNoRecords --------------- как выкинуть -------------- Public cnnAccess As New ADODB.Connection -------------------------------- Function Work() as Boolean Dim Result as Boolean cnnAccess.CursorLocation = adUseClient cnnAccess.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=\\Dom\D\Data\lab.mdb;" ' & _ 'cnnAccess.BeginTrans - строчка выкинута Result = AddProduct(Id_Customer, Name) 'If Result Then - строчка выкинута ' cnnAccess.RollbackTrans - строчка выкинута ' GoTo CancelHandler - строчка выкинута 'End If - строчка выкинута 'cnnAccess.CommitTrans - строчка выкинута cnnAccess.Close Set cnnAccess = Nothing Exit Sub CancelHandler: cnnAccess.Close Set cnnAccess = Nothing Work = True MsgBox "Error" End Sub ------------------------------ Function AddProduct(Id_Customer as Long, Name as String) as Boolean Dim rst As New ADODB.Recordset Dim sql As String sql = "SELECT * FROM Products Where Id_Product = 1" rst.Open sql, cnnAccess, adOpenDynamic, adLockOptimistic With rst .AddNew !Id_Customer = Id_Customer !Name = Name .Update AddProduct = True ' ПОСЛЕ ЭТОГО ВСЯ ТАБЛИЦА БЛОКИРУЕТСЯ ПОКА ИЗ ПРОГИ НЕ ВЫЙДЕШЬ!!! End With rst.Close Set rst = Nothing End Function ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 13:03 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Но я не могу выкинуть транзакцию, у меня добавляется куча товара и если вдруг ошибка где-то или просто юзер решил прервать процесс, то нужен полномаштабный откат всех изменений, иначе будет бардак, сами понимаете. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 13:20 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
-) переходим к пункту 2 ЗЫ - ООой-Ёй-ЁЁй - это што у вас там юзер в транзакции колбасит? далее почикано -) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 13:27 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Отсюда мораль - транзакция должна быть настолько короткой, насколько это возможно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 13:54 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Мораль сия меня не устраивает. Да и не правильно это, мне ведь решать какая транзакция будет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 16:07 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Пункт 2) окончился провалом, та же фигня, идет блокировка. Народ, как быть? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 16:13 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
авторМораль сия меня не устраивает. Да и не правильно это, мне ведь решать какая транзакция будет. Ну тогда Oracle, IB/FB и иже с ними тебе в руки. Иначе говоря версионники. Там пофигу длина транзакции. А в блокировочных механизмах транзакция должна быть как можно более короткой. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 16:17 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
самоцитата: авторнет ли там часом контрола, который Bound-ed к той же записи и "одновременно" с кодом редактирует ее? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 16:18 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
для Pavel - мнится, здеся версионник не поможет. Тут глыбь конкретная, версионник в ней не пловец сам по себе. версионнику как и всем остальным рулильщик нужен. тута конкретна на наложение транзакций похоже. а код не показывают. вот сижу и думаю - кому стыднее должно быть - тому кто спрашивает, или тому, кто отвечает... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 16:22 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
... или в самой постановке задачи допущены серьезные ошибки. Тут не только код, тут весь анамнез нужен с момента заражения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 16:26 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Ребят, контрола там нет. Я специально, дабы разобрать что к чему, сделал новый проект с одной лишь кнопкой, в которую запихнул весь код что обсуждается здесь, т.е. код касаемый непосредственно транзакции и добавления через рекордсет. Так что скрывать мне от вас нечего, код содержит не более того что мы обсуждаем здесь. Да и базу для экспериментов я новую создал, пустую. И завел там всего оку таблицу. Могу выслать, можете саби в дебагере посмотреть. А я лично склоняюсь к выводу что Access не умеет ограничивать блокировки одной записью в транзакциях. Давайте проверьте, создайте пустую базу, заведите там таблицу с одним полем, набейте десяток записей. И создайте VB проект с формой и кнопкой на ней и поиграйте с кодом и со всем что мне здесь советовали. Код, вешаемый на кнопку: Код: 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 16:36 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Жопа какая-то. Присоединяюсь к Павлу по поводу всего анамнеза (а мне ответили по поводу индексов?) А елси через Batch? Код: 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 16:49 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
А если SELECT вынеси из транзакции? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 16:55 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Через Batch блокировок нет, но и записи не добавляются, после завершения транзакции в таблице сколько было записей, столько и осталось. Не понял насчет анамнеза, звучит ругательно как-то, я же говорю что выложил весь неработающий код, зачем все модули выкладывать? Или это о другом? ЗЫ: достал я вас, примите извинения, но горю!!! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 16:57 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
авторИли это о другом? Так точно. Опиши бизнесс-процесс. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 17:00 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Через Batch блокировок нет, но и записи не добавляются, после завершения транзакции в таблице сколько было записей, столько и осталось. Что значит не добавляются? А если ручками вставлять - что будет? Ошибки какие-нибудь есть? Да тебе уже писали про INSERT - это лучше чем через рекодсеты - но мне до конца разобраться хотца. И в конце концов ответь: ИНДЕКСЫ ЕСТЬ??? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 17:02 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
adUseServer пробовал cnnAccess.Mode = 16 пробовал Jet OLEDB:Database Locking Mode=0 тоже Jet OLEDB:Database Locking Mode=1 тоже rst.CacheSize = 1 пробовал Select и открытие рекордсета выносил за транзакцию adLockBatchOptimistic и UpdateBatch туда же Чего бы еще замутить? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 17:02 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
В тестовой базе индексов нет, щас добавлю и глянем что будет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 17:03 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
авторSelect и открытие рекордсета выносил за транзакцию вот это неправда - не было такого щас попробую "твой код" - жди 5 мин ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 17:04 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Добавил ключевое поле, не помогло. Insert не устраивает потому что (об этом я умолчал, но без этого никак) нужно получить ID добавленной записи сразу после добавления! При Insert такого не могу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 17:06 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
авторвот это неправда - не было такого Здесь может я и не говорил, но по совету выше я это уже пробовал, ничего не вышло. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 17:07 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
А задача простая, импорт информации из внешнего источника в базу. Есть клиенты, заказы. Алгоритм следующий: добавляем обсуждаемым здесь методом клиента в таблицу клиентов, получаем его ID_Client, добавляем товар в товары, получаем его ID_Product, добавляем заказ клиента в таблицу заказов с учетом ID_Client и ID_Product. Вот собственно и все. Но грабли в то что одновременно с импортом, который длится минут 5, операторы набивают вручную заказы и клиентов и соответственно вылазят глюки что запись заблокирована. Если делать добавления через Insert, то придется вообще блокировать работу отдела, чтобы после Insert через Selectc Max(ID) получить ID товаров и клиентов, если не блокировать, то MAX может оказаться другим (кто-то ввел запись, а я еще не успел свой MAX отселектить). Потому и решил использовать AddNew вместо Insert, думая что добавляемые записи уж никак на работе не скажутся. Но кто же думал что Access будет и тут блокировать страницы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 17:16 |
|
||
|
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. 32. 33. 34. 35. 36. Пробую по старому через Update - все работает - все добавляется - ничего не блокируется - со всем Код: 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 17:17 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
авторInsert не устраивает потому что (об этом я умолчал, но без этого никак) нужно получить ID добавленной записи сразу после добавления! При Insert такого не могу. @@Identity ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 17:18 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Павел, какой @@Identity??? Это Access база! Виктор, а ты когда после Update стопорнул, т.е. когда транзакция все еще не завершена, открой таблицу и поменяй вручную значения ВСЕХ(!) записей. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 17:21 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Да, батч работает, стормознул немного, в смысле запись добавляется, но сабж по прежнему в силе. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 17:22 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
авторПавел, какой @@Identity??? Это Access база! Я понимаю. А ты попробуй (если у тебя Аcsess 2000 или более поздний). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 17:23 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
всЕ работает - с индексами и без, со скобками и без, внутри и снаружи и батч и не батч - никаких блокировок. Единственное - если попутать параметры - типа открыть для батчапдейт а апдейтить .Update - просто молча не добавляет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 17:25 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
всЕ работает - с индексами и без, со скобками и без, внутри и снаружи и батч и не батч - никаких блокировок. Единственное - если попутать параметры - типа открыть для батчапдейт а апдейтить .Update - просто молча не добавляет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 17:27 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Виктор, а ты когда после Update стопорнул, т.е. когда транзакция все еще не завершена, открой таблицу и поменяй вручную значения ВСЕХ(!) записей. Действительно. Если остановить прогу ПОСЛЕ Update. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 17:32 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Дык не только Клиенты - все таблицы заблокированы Это из-за конекта ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 17:35 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Pavel, 1) если mdb версии >=2000, то @@Identity у него ЕСТЬ 2) Еще раз - приведенный код ничего не блокирует, и , в принципе, честный, хотя свои "советы" оставляю в силе. Проблема НЕ в том коде непосредственно. Что-то утаивается. Выглядит объяснение твоего рассказа следующим образом: Есть два процесса А) и Б) а) открыл транзакцию а) добавил запись б) увидел добавленную запись б) открыл транзакцию (не обязательно) б) встал на редактирование записи и наложил блокировку а) закрыл транзакцию б) висит на записи до закрытия приложения, блокируя ее ПОЭТОМУ я говорил - ищи контрол. если это не контрол - то может, - "брошенный" незакрытый рекордсет ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 17:35 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
я понял - мы сражаемся с ветренными мельницами - так и должно быть при добавлении - блокировка всей таблицы на изменение ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.03.2004, 17:46 |
|
||
|
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 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Victosha Ну ты маньяк! Бегло просмотрел и пока не понял об чем собственно речь, о победе или поражении. Пойду углубленно изучать вопрос. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.03.2004, 14:06 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Я, конечно, поздно вступаю в дискуссию... Вначале её я думал, что вопрос простой, и поэтому помалкивал, в середине (когда к обсуждению вопроса подтянулись силы главного калибра) - казалось, что по существу вопроса всё уже сказано (или вот-вот будет сказано), и встревать в обсуждение со своими банальностями как-то не хотелось... А сейчас (перечитав дискуссию сверху донизу) я вижу, что никто, к моему вящему удивлению, не высказался достаточно полно по существу поставленного изначально вопроса, ответив определённо и убедительно - возможно ли то, что хотел автор, а если нет, то почему. Пытаюсь восполнить этот пробел. Насколько я понял, суть вопроса в том, что автор хочет, чтобы при использовании ADO (Microsoft Jet 4.0 OLE DB Provider) для доступа к MDB и применении client-side курсора при добавлении записи блокировалась только одна запись. Реально в этом случае блокируется страница. Подчеркну, что вопрос не в том, должна ли в конкретном примере здесь возникать блокировка - безусловно должна, учитывая конкретные обстоятельства, а лишь в том, какая у неё должна быть "гранулярность" - запись или страница. На основании некоторого опыта, довольно глубокого изучения материалов MSDN и результатов собственных экспериментов я пришёл к выводу, что это, похоже, невозможно из-за того, что конкретный ADO провайдер - Microsoft Jet 4.0 OLE DB Provider - такого не предусматривает (возможно, всего лишь по недосмотру). Вот почему я пришёл к такому выводу: Свойства объекта Connection - .Mode и .IsolationLevel, а также параметры метода открытия набора записей Open - CursorType и LockType в Microsoft Jet 4.0 влияют на лишь на то, должна или не должна быть блокировка и какая у неё должна быть продолжительность, но никак не затрагивают её детальность ("гранулярность"). Эта самая "гранулярность" (record locking/page locking) в Microsoft Jet 4.0 управляется следующим образом: 1. Меню в MS Access (у меня сейчас русский Access 2000): Сервис/Параметры, вкладка "Другие", параметр "Блокировка записей при открытии БД" 2. Специфическое свойство провайдера Microsoft Jet 4.0 OLE DB Provider для объекта ADODB.Connection: cnn.Properties("Jet OLEDB:Database Locking Mode") Page-level Locking - 0 Row-level Locking - 1 3. Специфическое свойство провайдера Microsoft Jet 4.0 OLE DB Provider для объекта ADODB.Recordset: rst.Properties("Jet OLEDB:Locking Granularity") Page-level locking - 1 Row-level locking - 2 Значение этого свойства принимается во внимание, лишь когда параметр "Jet OLEDB:Database Locking Mode" установлен как Row-level Locking. Следует отметить, что свойства 1) и 2) - это по сути, одно и то же свойство, и из них принимается во внимание то, что что будет включено раньше для конкретного сеанса (а последующие настройки будут игнорироваться). То есть, если мы откроем базу через программу MS Access, то в силу вступит настройка из меню, и она будет наследоваться всеми последующими соединениями (в том числе и из других программ). И наоборот. По умолчанию ADO Connection к БД Access открывается как .CursorLocation = adUseServer, и при этом свойство набора записей "Jet OLEDB:Locking Granularity" можно прочитать и настроить, как хочется. В этом случае в обсуждаемом примере (если все вышеназванные свойства настроены как надо) блокируется только одна добавляемая запись независимо от иных настроек - я проверял. Засада здесь вот в чём. Как только мы выполняем строку .CursorLocation = adUseClient, так из свойств объекта Recordset волшебным образом пропадает само свойство "Jet OLEDB:Locking Granularity"! То есть сlient-side курсоры для Microsoft Jet 4.0 OLE DB Provider вообще не поддерживают управление этой самой "гранулярностью"! Естественно, что с этого момента при добавлении записи блокироваться начинают страницами. Это меня окончательно убедило в том, что "this behaviour is by design", как пишут в MS Knowledge Base. Кстати, вот ещё что хотелось бы отметить. В этой теме неоднократно встречается код типа: Код: plaintext 1. Так вот, различные провайдеры ADO поддерживают не все комбинации параметров, и в определённых случаях создают в таких случаях набор записей не с "заказанными" параметрами, а "ближайшими" по их разумению к ним. В частности, в этом конкретном случае вместо набора записей типа adOpenKeyset будет создан набор записей adOpenStatic. Вообще, в случае .CursorLocation = adUseClient Microsoft Jet 4.0 OLE DB Provider ВСЕГДА создаёт набор записей с adOpenStatic, какое бы значение CursorType вы не указали. Кроме того, в этом случае бесполезно указывать вид блокировки adLockPessimistic - он будет заменён на adLockOptimistic. Отсюда вывод: желательно проверять, когда создаём recordset или connection, какой НА САМОМ ДЕЛЕ объект мы получили. Каждый ADO-провайдер себя ведёт здесь по своему, и даже один и тот же провайдер в зависимости от обстоятельств может вернуть не тот тип набора записей, на который мы рассчитывали, а другой. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.03.2004, 18:16 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Хочу уточнить у корифеев принципиальнцую возможность следующего: Для двух подключений Microsoft Jet 4.0 OLE DB Provider для объекта ADODB.Connection Код: plaintext 1. 2. 3. 4. 5. У меня такой фокус не проходит ни при каких параметрах подключения и рекордсета. Считал, что, при включенной транзакции, даже при Row-level Locking = 1 блокируется вся страница. ЗЫ: Видала я транзакции без блокировок, но что бы блокировки без транзакций... (с) Алиса в стране Акцесс. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.03.2004, 17:28 |
|
||
|
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
|
|||
|---|---|---|---|
|
#18+
Вы знаете, ещё немного поэкспериментировав и в очередной раз помусолив MSDN (из-за скудости информации там приходится читать ну прям буквально между строк!), я пришёл к неутешительному выводу: похоже (при использовании Microsoft Jet 4.0 OLE DB Provider), что никакая комбинация параметров НЕ ГАРАНТИРУЕТ блокировок на уровне записи, и если Jet считает, что нужно использовать страничную блокировку, то он таки её будет использовать, несмотря на твои указания. Максимум, что можно сколь-нибудь точно выяснить - это при каких обстоятельствах блокировки на уровне записей НЕ БУДЕТ. Честно говоря, мне не удалось добиться добавления записи в таблицу при наличии висящей транзакции, в которой ранее в ту же таблицу была добавлена запись, и склоняюсь к мысли, что это невозможно... Хотелось бы, чтобы меня переубедили. Более того, мне даже не удалось воспроизвести результаты моих прежних экспериментов, в которых добавление записи в таблицу не блокировало соседние записи. Все настройки, которые требуются для row-level locking, наличествуют, но что-то в окружении изменилось, и Jet упорно использует page-level locking... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.03.2004, 21:36 |
|
||
|
|

start [/forum/topic.php?all=1&fid=45&tid=1675750]: |
0ms |
get settings: |
9ms |
get forum list: |
20ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
166ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
105ms |
get tp. blocked users: |
2ms |
| others: | 238ms |
| total: | 561ms |

| 0 / 0 |
