powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
78 сообщений из 78, показаны все 4 страниц
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32452669
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
    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
        .Update
    End With
    
    rst.Close
    Set rst = Nothing



После .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 - не помогает.
Хелп!!!
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32452871
Фотография Victosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
поставь в AccessConnection.Mode=16 - ljk;yj dsktxbnm ndj. ,tle


Прим1

Код: plaintext
Все добавления делаются в транзакции
- это про что, про "встроенные транзакции" рассказ? что-то в приведенном тексте никаких транзакций не видно.
Код: plaintext
Ведь добавляемую в транзакции запись не видно, ее никто не изменит
это как бы не совсем верно, если не сказать - совсем неверно.

Прим2 - если тебе не нужно работать с отстоединенными рекордсетами И не нужен RecordCount- не используй фвГыуСдшуте - кроме доп. перегрузки на память и некоторого замедления - другой пользы не получишь. используй adUseClient
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32452874
Фотография Victosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в смысле - поставь в AccessConnection.Mode=16 - должно вылечить твою беду
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32452970
Фотография Лифчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторне используй фвГыуСдшуте
Какой хароший савет, суший! Моя тожи всигда думаль, шта нинада исползувать "фвГыуСдшуте", тока боялась сказать штоб за фуфло ни сойти. Тыж мою мысль своими славами изложил тут прям в Ынтернете. спасиба!

ЗЫ
Просто не мог хоть как-то не отметиться в топике у автора с таким ником
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32452988
Фотография Victosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
To Лифчик
будем считать, что познакомились.
-)
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32453003
Фотография Victosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а совет был про adUseServer - в смысле его используй.

PS
пальчы жмакают быстрее, чем глазки смотрют. Правда севодни они и смотрют плохо с утра.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32453171
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Народ, я забыл сказать что все эти операции я делаю из VB клиента. Т.е. есть прога на VB из которой идет обращение в базу Access 2000.

Victosha
AccessConnection.Mode=16 это применимо если работать с ADO в Access? А как с VB быть?

Транзакции там есть, просто не стал их описывать, банальные
.BeginTrans
.CommitTrans

авторВедь добавляемую в транзакции запись не видно, ее никто не изменит

это как бы не совсем верно, если не сказать - совсем неверно.
Это еще почему?

авторфвГыуСдшуте
Я весь пол вытер пока ржал ))))

Лифчик
Ты бы помог бы лучше, чем истерику тут разводить :)

adUseServer использовать не могу, мне нужен RecordCount, но разве из-за adUseServer у меня таблицы блокируются?
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32453212
Фотография Victosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
это глазки - они ведели, что человекк плакал, а пальцы жмакают по памяти.
имелось ввиду следующее

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. а он в руках (твоих).
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32453216
Фотография Victosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
зы2 про adUseServer - исключительно из совета экономить ресурсы (комуктера) 
- в смысле компуктера
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32453307
Фотография Senin Viktor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
есть такое параметер у ADODB.Connection
"Jet OLEDB:Database Locking Mode"
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
The Jet OLEDB:Database Locking Mode property can be set to any of the following 
values:

Page-level Locking                       0 

Row-level Locking                        1 

Note   A database can only be open in one mode at a time. The first user to open 
the database determines the locking mode to be used while the database is open.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32454195
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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.
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
 ------------------------------
 


Самое интересное: попробовал испытать на тестовой базе. Создал базу, создал в ней простую таблицу, запустил код - после Update если попытаться редактировать любую запись в таблице Access выдает: <Обновление невозможно; установлена блокировка>
Меняю adOpenDynamic на adOpenKeyset - ура! после Update записи даются редактировать. Пошел заменил в основной базе adOpenDynamic на adOpenKeyset, вроде срабатывает, записи редактируемые после Update, но через некоторое время работы они опять блокируются и каким образом не пойму.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32454201
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Блин, правки сообщений тут нет что ли?
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32454330
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ребят, обнаружилось что все же блокируется не вся таблица, а некоторая ее часть (называется страница?). Уже лучше. Как бы добиться блокировки только одной записи.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32454525
Фотография Pavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Перейти на MSDE.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32454536
Фотография Senin Viktor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2Pavel
Перейти на MSDE.

Ну и там страничная блокировка есть :)

2Pantalone

Ты пробовла мой совет про Row locking?

Как бы добиться блокировки только одной записи.

в общем - это решает оптимизатор - какой способ блокировки ему выгодней - такой и будет использоваться, что бы ты не написал и не сделал.

З.Ы.
А индексы (ПримариКей и пр.) есть в Products ?
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32454558
Фотография Victosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32454626
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cnnAccess.Mode=16 не помогло.

cnnAccess.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\biblio.mdb;Jet OLEDB:Database Locking Mode=1"
Тоже.

Что такое авторнаружные транзакционные скобки и как их выкинуть?
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32454689
Фотография Victosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вкралась очепятка
имелось ввиду
.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
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32454724
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Но я не могу выкинуть транзакцию, у меня добавляется куча товара и если вдруг ошибка где-то или просто юзер решил прервать процесс, то нужен полномаштабный откат всех изменений, иначе будет бардак, сами понимаете.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32454740
Фотография Victosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-)
переходим к пункту 2

ЗЫ - ООой-Ёй-ЁЁй - это што у вас там юзер в транзакции колбасит?

далее почикано
-)
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32454824
Фотография Pavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Отсюда мораль - транзакция должна быть настолько короткой, насколько это возможно.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455230
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мораль сия меня не устраивает. Да и не правильно это, мне ведь решать какая транзакция будет.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455242
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пункт 2) окончился провалом, та же фигня, идет блокировка.
Народ, как быть?
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455254
Фотография Pavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторМораль сия меня не устраивает. Да и не правильно это, мне ведь решать какая транзакция будет.
Ну тогда Oracle, IB/FB и иже с ними тебе в руки. Иначе говоря версионники. Там пофигу длина транзакции. А в блокировочных механизмах транзакция должна быть как можно более короткой.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455258
Фотография Victosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
самоцитата:
авторнет ли там часом контрола,
который Bound-ed к той же записи и "одновременно" с кодом редактирует ее?
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455270
Фотография Victosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
для Pavel - мнится, здеся версионник не поможет. Тут глыбь конкретная, версионник в ней не пловец сам по себе. версионнику как и всем остальным рулильщик нужен. тута конкретна на наложение транзакций похоже. а код не показывают.
вот сижу и думаю - кому стыднее должно быть - тому кто спрашивает, или тому, кто отвечает...
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455279
Фотография Pavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
... или в самой постановке задачи допущены серьезные ошибки. Тут не только код, тут весь анамнез нужен с момента заражения.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455310
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ребят, контрола там нет.
Я специально, дабы разобрать что к чему, сделал новый проект с одной лишь кнопкой, в которую запихнул весь код что обсуждается здесь, т.е. код касаемый непосредственно транзакции и добавления через рекордсет. Так что скрывать мне от вас нечего, код содержит не более того что мы обсуждаем здесь. Да и базу для экспериментов я новую создал, пустую. И завел там всего оку таблицу. Могу выслать, можете саби в дебагере посмотреть.
А я лично склоняюсь к выводу что 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.
Dim cnnAccess As New ADODB.Connection

Dim rst As New ADODB.Recordset
Dim sql As String

cnnAccess.CursorLocation = adUseClient
cnnAccess.Open  "Provider=Microsoft.Jet.OLEDB.4 . 0 ;" & _
            "Data Source=C:\biblio.mdb;" 

cnnAccess.BeginTrans


    sql =  "SELECT * FROM Authors Where Author = '1'" 
    
    rst.Open sql, cnnAccess, adOpenKeyset, adLockOptimistic
    
    With rst
        .AddNew
            !Author =  "Name" 
        .Update
        ' тут останавливаемся и пытаемся в базе поредактировать все записи.
    End With
    
    rst.Close
    Set rst = Nothing


cnnAccess.CommitTrans

cnnAccess.Close
Set cnnAccess = Nothing

...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455352
Фотография Senin Viktor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Жопа какая-то. Присоединяюсь к Павлу по поводу всего анамнеза (а мне ответили по поводу индексов?)

А елси через 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.
Dim cnnAccess As New ADODB.Connection

Dim rst As New ADODB.Recordset
Dim sql As String

cnnAccess.CursorLocation = adUseClient
cnnAccess.Open  "Provider=Microsoft.Jet.OLEDB.4 . 0 ;" & _
            "Data Source=C:\biblio.mdb;" 

cnnAccess.BeginTrans


    sql =  "SELECT [Author] FROM Authors Where 0 = 1 "
    
rst.Open sql, cnnAccess, adOpenKeyset, adLockBatchOptimistic
    
    With rst
        .AddNew
            !Author =  "Name" 

        .UpdateBatch
        ' тут останавливаемся и пытаемся в базе поредактировать все записи.
    End With
    
    rst.Close
    Set rst = Nothing


cnnAccess.CommitTrans

cnnAccess.Close
Set cnnAccess = Nothing
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455374
Фотография Pavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А если SELECT вынеси из транзакции?
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455377
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Через Batch блокировок нет, но и записи не добавляются, после завершения транзакции в таблице сколько было записей, столько и осталось.
Не понял насчет анамнеза, звучит ругательно как-то, я же говорю что выложил весь неработающий код, зачем все модули выкладывать? Или это о другом?

ЗЫ: достал я вас, примите извинения, но горю!!!
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455382
Фотография Pavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторИли это о другом?
Так точно. Опиши бизнесс-процесс.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455384
Фотография Senin Viktor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Через Batch блокировок нет, но и записи не добавляются, после завершения транзакции в таблице сколько было записей, столько и осталось.


Что значит не добавляются? А если ручками вставлять - что будет? Ошибки какие-нибудь есть?

Да тебе уже писали про INSERT - это лучше чем через рекодсеты - но мне до конца разобраться хотца.

И в конце концов ответь: ИНДЕКСЫ ЕСТЬ???
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455385
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
adUseServer пробовал
cnnAccess.Mode = 16 пробовал
Jet OLEDB:Database Locking Mode=0 тоже
Jet OLEDB:Database Locking Mode=1 тоже
rst.CacheSize = 1 пробовал
Select и открытие рекордсета выносил за транзакцию
adLockBatchOptimistic и UpdateBatch туда же

Чего бы еще замутить?
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455387
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В тестовой базе индексов нет, щас добавлю и глянем что будет.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455389
Фотография Victosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторSelect и открытие рекордсета выносил за транзакцию
вот это неправда - не было такого

щас попробую "твой код" - жди 5 мин
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455397
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добавил ключевое поле, не помогло.
Insert не устраивает потому что (об этом я умолчал, но без этого никак) нужно получить ID добавленной записи сразу после добавления! При Insert такого не могу.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455399
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторвот это неправда - не было такого
Здесь может я и не говорил, но по совету выше я это уже пробовал, ничего не вышло.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455419
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А задача простая, импорт информации из внешнего источника в базу. Есть клиенты, заказы. Алгоритм следующий: добавляем обсуждаемым здесь методом клиента в таблицу клиентов, получаем его ID_Client, добавляем товар в товары, получаем его ID_Product, добавляем заказ клиента в таблицу заказов с учетом ID_Client и ID_Product. Вот собственно и все. Но грабли в то что одновременно с импортом, который длится минут 5, операторы набивают вручную заказы и клиентов и соответственно вылазят глюки что запись заблокирована.
Если делать добавления через Insert, то придется вообще блокировать работу отдела, чтобы после Insert через Selectc Max(ID) получить ID товаров и клиентов, если не блокировать, то MAX может оказаться другим (кто-то ввел запись, а я еще не успел свой MAX отселектить). Потому и решил использовать AddNew вместо Insert, думая что добавляемые записи уж никак на работе не скажутся. Но кто же думал что Access будет и тут блокировать страницы.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455420
Фотография Senin Viktor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
пробую на Борее через батч - все работает - все появляется

Код: 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.
Dim cnnAccess As New ADODB.Connection

Dim rst As New ADODB.Recordset
Dim sql As String

Sub s()


cnnAccess.CursorLocation = adUseClient
cnnAccess.Open  "Provider=Microsoft.Jet.OLEDB.4 . 0 ;" & _
            "Data Source=C:\Program Files\Microsoft Office\Office\Samples\Борей.mdb;" 

cnnAccess.BeginTrans


    sql =  "SELECT [КодКлиента],Название FROM Клиенты Where 0 = 1 "
    
rst.Open sql, cnnAccess, adOpenKeyset, adLockBatchOptimistic
    
    With rst
        .AddNew
            ![КодКлиента] =  "QWsWQ" 
            ![Название] =  "ddddd" 
        .UpdateBatch
        ' тут останавливаемся и пытаемся в базе поредактировать все записи.
    End With
    
    rst.Close
    Set rst = Nothing


cnnAccess.CommitTrans

cnnAccess.Close
Set cnnAccess = Nothing

End Sub


Пробую по старому через 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.
Sub s()


cnnAccess.CursorLocation = adUseClient
cnnAccess.Open  "Provider=Microsoft.Jet.OLEDB.4 . 0 ;" & _
            "Data Source=C:\Program Files\Microsoft Office\Office\Samples\Борей.mdb;" 

cnnAccess.BeginTrans


    sql =  "SELECT [КодКлиента],Название FROM Клиенты Where 0 = 1 "
    
rst.Open sql, cnnAccess, adOpenKeyset, adLockOptimistic
    
    With rst
        .AddNew
            ![КодКлиента] =  "_йУWQ" 
            ![Название] =  "dddййййd" 
        .Update
        ' тут останавливаемся и пытаемся в базе поредактировать все записи.
    End With
    
    rst.Close
    Set rst = Nothing


cnnAccess.CommitTrans

cnnAccess.Close
Set cnnAccess = Nothing

End Sub
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455422
Фотография Pavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторInsert не устраивает потому что (об этом я умолчал, но без этого никак) нужно получить ID добавленной записи сразу после добавления! При Insert такого не могу.
@@Identity
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455427
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Павел, какой @@Identity??? Это Access база!

Виктор, а ты когда после Update стопорнул, т.е. когда транзакция все еще не завершена, открой таблицу и поменяй вручную значения ВСЕХ(!) записей.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455431
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, батч работает, стормознул немного, в смысле запись добавляется, но сабж по прежнему в силе.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455433
Фотография Pavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторПавел, какой @@Identity??? Это Access база!
Я понимаю.
А ты попробуй (если у тебя Аcsess 2000 или более поздний).
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455437
Фотография Victosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
всЕ работает - с индексами и без, со скобками и без, внутри и снаружи и батч и не батч - никаких блокировок.

Единственное - если попутать параметры - типа открыть для батчапдейт а апдейтить .Update - просто молча не добавляет.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455439
Фотография Victosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
всЕ работает - с индексами и без, со скобками и без, внутри и снаружи и батч и не батч - никаких блокировок.

Единственное - если попутать параметры - типа открыть для батчапдейт а апдейтить .Update - просто молча не добавляет.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455452
Фотография Senin Viktor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Виктор, а ты когда после Update стопорнул, т.е. когда транзакция все еще не завершена, открой таблицу и поменяй вручную значения ВСЕХ(!) записей.

Действительно. Если остановить прогу ПОСЛЕ Update.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455459
Фотография Senin Viktor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дык не только Клиенты - все таблицы заблокированы
Это из-за конекта
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455460
Фотография Victosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Pavel,
1) если mdb версии >=2000, то @@Identity у него ЕСТЬ
2) Еще раз - приведенный код ничего не блокирует, и , в принципе, честный, хотя свои "советы" оставляю в силе. Проблема НЕ в том коде непосредственно. Что-то утаивается.

Выглядит объяснение твоего рассказа следующим образом:
Есть два процесса А) и Б)

а) открыл транзакцию
а) добавил запись
б) увидел добавленную запись
б) открыл транзакцию (не обязательно)
б) встал на редактирование записи и наложил блокировку

а) закрыл транзакцию
б) висит на записи до закрытия приложения, блокируя ее

ПОЭТОМУ я говорил - ищи контрол.

если это не контрол - то может, - "брошенный" незакрытый рекордсет
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455482
Фотография Senin Viktor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я понял - мы сражаемся с ветренными мельницами - так и должно быть при добавлении - блокировка всей таблицы на изменение
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455561
Фотография Victosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
to Senin Viktor не мог бы ты пояснить - что именно ты понял

я точно понял только одно - блокировка при открытой транзакции существует на отрезке времени между update и commit - собственно том отрезке, когда непосредственно в базе журналируются изменения состояний таблиц.

То есть, это БЫЛО бы проблемой отложенного commit-a, если бы человек не утверждал, что база освобождается только при закрытии приложения.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455748
Фотография Senin Viktor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2Victosha
>>
я точно понял только одно - блокировка при открытой транзакции существует на отрезке времени между update и commit - собственно том отрезке, когда непосредственно в базе журналируются изменения состояний таблиц.

Вот имеено - на этом отрезке мы все и пытались отредактирвоать данные - BeginTran - Update - попытка редактировать заблокированную таблицу - CommitTran.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455775
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Знаете, я немного погорячился сказав что таблица разблокируется только после завершения программы, конечно я имел в виду завершение транзакции.

Senin Viktor
Я специально не проверял, но все же мне кажется блокируются не все таблицы, а именно тех в которых был вызван Update. У меня в базе таблиц штук 100, а юзеры начинают бегать только с воплями что клиенты не заводятся или их заказы, т.е. как раз в те таблицы в которые я закачиваю, в остальном вроде тихо, иначе бы такой вой поднялся!

Victosha
Код блокирует, говорю же тебе, остановить сразу после Update не доходя до CommitTran и проверь. Senin Viktor ведь это подтвердил. И что за мания следователя? Ничего я не утаиваю! :) Я уже привел отдельный конкретный экспирементальный образец базы и приложения, где всего один процесс, одна транзакция и один рекордсет, никаких контролов более!

Я все же не вижу логики зачем Jet понадобилось блокировать таблицу после добавления записи.

Люди, черт с ними с рекордсетами, если уж так все запущено.
Давайте разберемся как провернуть этот фокус с @@Identity.
Первый раз слышу что такое можно не в хранимой процедуре, а в базе Access. Надеюсь что мне повезло, потому что база именно Access 2000.
Как будет выглядеть код?
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455938
Фотография Victosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну чтож, можно считать, открытие состоялось. Сие великое поведение есть результат комбинации именно adUseClient и дефолтного adXactReadCommitted уровня изоляции.

To Senin Viktor – вот как раз этого – что между update и Commit у автора вопроса что-то происходит я упорно и не видел.

To Pantalone - буду бурчать - терпи.
Ты шибко-то не серчай. Никакой тайной мысли тебя обижать не было, а было явное стремление выудить детали происходящего. До опыта кажется, что это в первую очередь твой интерес. В опыте правда почудилось, что ты просто посмеяться над людями задумал, как та девочка, что бросает свою игрушку в лужу, а потом показывает пальцем на мальчика, который ее вернул, смеясь над тем, что он грязный. (копирайт от Берна). А, оказывается, я сам во всем этом. Можно было бы и раньше ситуацию опознать – читая назад видно – намеки разбросаны. Ну вот не знал я такой мудрой в своей конкретности детали – НЕ ЗНАЛ. И представить себе, что именно в этом углу искать надо – не мог, по культурным своим заборам. Диагноз-то все-таки поставлен, что и есть медалью на грудях и залогом длинной жизни. А то, что дохтур злобный и глупый – как видишь, это не смертельно. Оно же ведь - все знать можно, только вне пространства находясь.
ЗЫ получается длинно - потому будет двумя постами
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32455940
Фотография Victosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
теперь по существу исходного вопроса.
Понижение уроня блокировки до adXactReadUncommitted при сохранении adUseClient решает проблему блокировки. При adUseServer блокировки не возникает вообще, но урвень изоляции остается фактически adXactReadCommitted, независимо от того, что говоришь соединению - это как раз то, о чем мечтает и чего не хочет автор вопроса (потому что ему нужен рекордкаунт).

ЗЫ Была мысля разродится примерами с пояснениями, но что - то загрустилось - видно пора в холодильник
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32456045
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Victosha
При adUseServer блокировки не возникает вообще
Попробуй еще раз. При количестве записей в таблице штук 10.

Понижение уроня блокировки до adXactReadUncommitted при сохранении adUseClient решает проблему блокировки.
adXactReadUncommitted это где, это кто?

Снова появилась надежда разобраться с рекордсетами, уж больно неохота на Insert переходить, лень - двигатель прогесса как известно :)
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32456070
Фотография Senin Viktor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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.
Option Compare Database
Option Explicit

Dim rst As New ADODB.Recordset
Dim sql As String
Dim cnnAccess As ADODB.Connection
Sub s()
    Set cnnAccess = New ADODB.Connection

    With cnnAccess
        .CursorLocation = adUseClient
        .IsolationLevel = adXactReadUncommitted
        '.Mode = adModeShareExclusive
    End With
    cnnAccess.Open "PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=C:\Program Files\Microsoft Office\Office\Samples\Борей.mdb;PERSIST SECURITY INFO=FALSE;Jet OLEDB:System database=C:\PROGRA~1\COMMON~1\System\SYSTEM.MDW"

    cnnAccess.BeginTrans


    sql = "SELECT [КодКлиента],Название FROM Клиенты Where 0=1"

    rst.CursorLocation = adUseClient
    rst.Open sql, cnnAccess, adOpenKeyset, adLockOptimistic

    With rst
        .AddNew
        ![КодКлиента] = "_nssQ"
        ![Название] = "dddййййd"
        .Update
        ' тут останавливаемся и пытаемся в базе поредактировать все записи.
    End With

    rst.Close
    Set rst = Nothing


    cnnAccess.CommitTrans

    cnnAccess.Close
    Set cnnAccess = Nothing

End Sub
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32456100
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, робяты, при adXactReadUncommitted та же хрень.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32456320
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Видимо труба.
Давайте с @@Identity попробуем, хотя у меня и Access 2000 но в хелпе по этому вопросу шаром покати.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32456459
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати вот тут интересный примерчик на тему получения ID добавленной записи. Интересный потому что непонятно зачем там для этого используется bookmark, absolutePosition и Requery? Когда ID новой записи и без этого сразу видно после Update
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32456462
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Собственно @@Identity для Jet OLE DB Provider Version 4.0
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32456467
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все понятно, там выцарапывается ID при добавлении записи в SQL Server. Для Access это все лишнее, ID сразу виден.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32456508
Фотография Pavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это если через рекордсет добавлять. А если запросом то нужно.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32456567
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Шеф, все пропало!!! (с) Б. Рука

Код: 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.
cnnAccess.CursorLocation = adUseClient
cnnAccess.Open  "Provider=Microsoft.Jet.OLEDB.4 . 0 ;" & _
            "Data Source=C:\biblio.mdb;" 

cnnAccess.BeginTrans

    sql =  "INSERT INTO Authors "  & _
              "(Author) VALUES ('AutoIncrement Test')" 
    cnnAccess.Execute sql, , adCmdText + adExecuteNoRecords
    
    'УЖЕ ТУТ ТАБЛИЦА ЗАБЛОКИРОВАНА
    'СЛЕДОВАТЕЛЬНО БЛОКИРОВКА ИДЕТ ОТ Connection
    
    
    Dim rst As New ADODB.Recordset
    Dim sql As String
    
    sql =  "SELECT @@Identity" 
    
    rst.Open sql, cnnAccess, adOpenForwardOnly, adLockOptimistic, adCmdText
    MsgBox rst( 0 ).Value

   
    rst.Close
    Set rst = Nothing


cnnAccess.CommitTrans

cnnAccess.Close
Set cnnAccess = Nothing



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.

Остается только разрыдаться на плече Билла
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32456678
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я убью его!!! (с) Б. Рука
:)
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32456683
Фотография Senin Viktor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Рыдать не надо - Pavel выше уже сказал - транзакции должны быть короткими - ты сразу после Execute делай CommitTran и затемполучай свой идентити и не парся.

З.Ы.
По возможности - ни каких циклов по рекордсетам (вообще от рекодсетов отказаться надо - в пользу SQL-языка), по возможности активно использовать временные таблицы, в которые заливать данные и уже в транзакции, одним оператором, быстро выполнять обновление. Способов много, еще их больше на MS SQL.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32456747
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Senin Viktor сразу после Execute делай CommitTran и затемполучай свой идентити и не парся.

А как я откат буду делать всего что уже назаливал в базу к моменту ошибки или отмены юзером???
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32456822
Фотография Senin Viktor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А как я откат буду делать всего что уже назаливал в базу к моменту ошибки или отмены юзером???

Есть такая легенда про юзера который начал редактировать таблицу (есно, она заблокировалась) и ... ушел в отпуск - так вот если не изменишь подход - то эта легенда станет явью. Для тебя.

З.Ы.
Не зная логики работы твоей проги (и вообще чегонужно) - трудно давать какие-либо советы. Только общие.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32456843
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это не легенда, а пример как бывает когда юзер редактирует запис и не окончив это радостно топает на обед. Заблокирована там вроде оказывается всего одна запись.
Да ладно, это все шутки, то что логику менять придется это ясен пень. Жаль что мельницу не победили.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32457106
Фотография Pavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
К счастью для меня это стало легендой. А когда-то было кошмаром, и имя кошмару - Paradox.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32457988
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код поменял, теперь все делается за секунды, но находятся несчастные юзеры, которые умудряются и за эти секунды со мной пересечься.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32458007
Фотография Senin Viktor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Секунд ы - это много, хотя фиг тебя знает - м.б. ты ядерный взрыв моделируешь :)
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32458037
Фотография Victosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
приношу извинения за вчерашнее молчание - несколько ежом по сковордке день оказался,

"ОТКРЫТИЕ" придется ЗАКРЫТЬ (с двойным изумлением)

постараюсь вечером подробный отчет
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32459404
Фотография Victosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Отчет об истории с «открытием». Как могу, подробно.

Началось с того, что решил нарисовать пару «классических учебных» примеров по работе с транзакциями (как надо и нет) для 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

'вот как будто и вся история
' ничего хорошего в ней нет
'(((
'А выписывать ее оказалось дольше ожидаемого.
'(((
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32459490
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Victosha
Ну ты маньяк! Бегло просмотрел и пока не понял об чем собственно речь, о победе или поражении. Пойду углубленно изучать вопрос.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32459605
Я, конечно, поздно вступаю в дискуссию... Вначале её я думал, что вопрос простой, и поэтому помалкивал, в середине (когда к обсуждению вопроса подтянулись силы главного калибра) - казалось, что по существу вопроса всё уже сказано (или вот-вот будет сказано), и встревать в обсуждение со своими банальностями как-то не хотелось...

А сейчас (перечитав дискуссию сверху донизу) я вижу, что никто, к моему вящему удивлению, не высказался достаточно полно по существу поставленного изначально вопроса, ответив определённо и убедительно - возможно ли то, что хотел автор, а если нет, то почему.

Пытаюсь восполнить этот пробел.

Насколько я понял, суть вопроса в том, что автор хочет, чтобы при использовании 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.
    rst.CursorLocation = adUseClient
    rst.Open sql, cnnAccess, adOpenKeyset, adLockOptimistic


Так вот, различные провайдеры ADO поддерживают не все комбинации параметров, и в определённых случаях создают в таких случаях набор записей не с "заказанными" параметрами, а "ближайшими" по их разумению к ним. В частности, в этом конкретном случае вместо набора записей типа adOpenKeyset будет создан набор записей adOpenStatic. Вообще, в случае .CursorLocation = adUseClient Microsoft Jet 4.0 OLE DB Provider ВСЕГДА создаёт набор записей с adOpenStatic, какое бы значение CursorType вы не указали. Кроме того, в этом случае бесполезно указывать вид блокировки adLockPessimistic - он будет заменён на adLockOptimistic.

Отсюда вывод: желательно проверять, когда создаём recordset или connection, какой НА САМОМ ДЕЛЕ объект мы получили. Каждый ADO-провайдер себя ведёт здесь по своему, и даже один и тот же провайдер в зависимости от обстоятельств может вернуть не тот тип набора записей, на который мы рассчитывали, а другой.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32459872
acol
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Хочу уточнить у корифеев принципиальнцую возможность следующего:

Для двух подключений Microsoft Jet 4.0 OLE DB Provider для объекта ADODB.Connection

Код: plaintext
1.
2.
3.
4.
5.
      Подключение А                     Подключение Б
 1     Открывается                        Открывается
 2     Начинает транзакцию             
 3     Вносит данные в таблицу Y
 4                                        Вносит данные в таблицу Y 
 5     Закрывает транзакцию



У меня такой фокус не проходит ни при каких параметрах подключения и рекордсета. Считал, что, при включенной транзакции, даже при Row-level Locking = 1 блокируется вся страница.

ЗЫ: Видала я транзакции без блокировок, но что бы блокировки без транзакций... (с) Алиса в стране Акцесс.
...
Рейтинг: 0 / 0
ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
    #32459924
Вы знаете, ещё немного поэкспериментировав и в очередной раз помусолив MSDN (из-за скудости информации там приходится читать ну прям буквально между строк!), я пришёл к неутешительному выводу: похоже (при использовании Microsoft Jet 4.0 OLE DB Provider), что никакая комбинация параметров НЕ ГАРАНТИРУЕТ блокировок на уровне записи, и если Jet считает, что нужно использовать страничную блокировку, то он таки её будет использовать, несмотря на твои указания.
Максимум, что можно сколь-нибудь точно выяснить - это при каких обстоятельствах блокировки на уровне записей НЕ БУДЕТ.

Честно говоря, мне не удалось добиться добавления записи в таблицу при наличии висящей транзакции, в которой ранее в ту же таблицу была добавлена запись, и склоняюсь к мысли, что это невозможно... Хотелось бы, чтобы меня переубедили.

Более того, мне даже не удалось воспроизвести результаты моих прежних экспериментов, в которых добавление записи в таблицу не блокировало соседние записи. Все настройки, которые требуются для row-level locking, наличествуют, но что-то в окружении изменилось, и Jet упорно использует page-level locking...
...
Рейтинг: 0 / 0
78 сообщений из 78, показаны все 4 страниц
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / ADO Recordset блокирует всю таблицу, нужно блокировать только редактируемую запись.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]