Транзакции

Работа VB и СУБД (Access, MSSQL, MySQL, Oracle и пр.)
Правила форума
При создании новой темы не забывайте указывать используемую СУБД.
Алексей К.
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 419
Зарегистрирован: 12.05.2004 (Ср) 9:41
Откуда: Ульяновск

Транзакции

Сообщение Алексей К. » 21.03.2005 (Пн) 10:08

База ацевская, подключаюсь через DAO. Как сделать чтобы несколько пользователей могли изменять определенную запись.
Попробовал сделать одновременное обращение к базе на изменение (запускал два экзешника и пока первый не закончил работу обращался к базе из второго)
Второй экзешник ругается: "Обновление невозможно; блокировка установлена пользователем <имя> на машине <имя>. (Ошибка 3260)"
Мне нужно чтобы изменения вызванные вторым экзешником тоже учитывались. Вроде бы нужно в таких ситуациях применять транзакции (а может и нет), но я признаюсь - в них не шарю :( .
Подскажите пожалуйста как быть, буду признателен за пример кода.
Вот код проекта, который я дважды запускал на исполнение:
Код: Выделить всё

Private Sub Command1_Click()
ProgressBar1.Min = 1
ProgressBar1.Max = 10000
ProgressBar1.Visible = True
On Error GoTo errhndl
Set db = OpenDatabase(App.Path + "\" + "mmm.mdb", False)
Set rs = db.OpenRecordset("обращений")
rs.MoveFirst
For i = 1 To 10000
rs.Edit
f = rs("раз")
rs("раз") = f + CInt(i)
ProgressBar1.Value = i
DoEvents
rs.Update
Next i
rs.Close
db.Close
ProgressBar1.Visible = False
exit sub
errhndl:
MsgBox (Err.Number)
End Sub

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 21.03.2005 (Пн) 10:13

Открывай, устанавливая оптимистический режим блокировки.
Lasciate ogni speranza, voi ch'entrate.

Алексей К.
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 419
Зарегистрирован: 12.05.2004 (Ср) 9:41
Откуда: Ульяновск

Сообщение Алексей К. » 21.03.2005 (Пн) 10:18

Это как? Подскажи если не трудно

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 21.03.2005 (Пн) 10:29

В DAO:
Код: Выделить всё
Set recordset = object.OpenRecordset (dbOpenDynaset, , dbOptimistic)
Lasciate ogni speranza, voi ch'entrate.

Алексей К.
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 419
Зарегистрирован: 12.05.2004 (Ср) 9:41
Откуда: Ульяновск

Сообщение Алексей К. » 21.03.2005 (Пн) 10:47

Set rs = db.OpenRecordset("обращений", dbOpenDynaset, , dbOptimistic)
ругается:
Ошибочный аргумент. (Ошибка 3001)
Что не так делаю

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 21.03.2005 (Пн) 10:57

А таблица "обращений" существует?
Lasciate ogni speranza, voi ch'entrate.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 21.03.2005 (Пн) 11:00

Хм... А придется подключаться через ODBC, чтобы использовать такой тип блокировки.
Lasciate ogni speranza, voi ch'entrate.

Алексей К.
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 419
Зарегистрирован: 12.05.2004 (Ср) 9:41
Откуда: Ульяновск

Сообщение Алексей К. » 21.03.2005 (Пн) 11:03

Табличка такая есть точно, Буду пробовать через ODBC

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 21.03.2005 (Пн) 11:10

Тогда лучше уж переходи на ADO.
DAO рулит в связке с Jet.
Lasciate ogni speranza, voi ch'entrate.

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 21.03.2005 (Пн) 12:44

Алексей К. писал(а):Set rs = db.OpenRecordset("обращений", dbOpenDynaset, , dbOptimistic)
ругается:
Ошибочный аргумент. (Ошибка 3001)
Что не так делаю


Давно с DAO не работал, но в данном случае похоже надо все параметры указывать...
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

Krasavica
Небожительница
Небожительница
Аватара пользователя
 
Сообщения: 1378
Зарегистрирован: 04.11.2003 (Вт) 17:51
Откуда: Россия, город-герой Москва ;-)

Сообщение Krasavica » 21.03.2005 (Пн) 19:15

Алексей К.

Транзакции тут не совсем к месту.

На самом деле это большая проблема - одна из её ветвей потерянные обновления: например пользователь 1 и 2 обратились к записи в состоянии 1. Потом пользователь 1 изменил запись и перевёл её в состояние 2, после этого пользователь 2 изменил запись и перевёл её в состояние 3. В результате изменения внесённые пользователем 1 были утеряны.

Насколько мне известно MS Access не предоставлет механизма одновременного редактирования одной записи несколькими пользователями. Если Вам это требуется то нужный механизм следует реализовывать на уровне приложения. :wink:
я - ангел!!! ...просто крылья в стирке, а нимб на подзарядке!
Меня трудно найти, легко потерять и невозможно забыть.Изображение

Ennor
Конструктивный критик
Конструктивный критик
 
Сообщения: 2504
Зарегистрирован: 18.12.2001 (Вт) 3:58
Откуда: Калуга -> Москва

Сообщение Ennor » 22.03.2005 (Вт) 3:52

Одновременное редактирование записи вообще ни одна СУБД не поддерживает. Те, которые поддерживают - типа Oracle - на самом деле лишь делают вид. А все потому, что логически такая ситуация невозможна: запрос от одного пользователя всегда приходит раньше другого. Раньше даже в том случае, если эти два идиота сидят рядом и "на раз-два-три" кнопки нажимают - при той модели многопоточности, которую реализует Windows, один из потоков окажется в очереди на обработку раньше другого, вот и вся любовь.

Теперь насчет практики: пользователей двое, а запись одна, и оба хотят, чтобы именно их изменения остались в БД. Ну и как это сделать? Подавляющее большинство систем подходит к данному вопросу с позиции "Кто последний, тот и папа". Как следствие, БД должна отрабатывать любой запрос на изменение записи, ибо она не знает, будет эта запись изменена еще раз через полсекунды, или через полгода.

Таким образом, если нужно хранить все версии данных, то следует заранее закладываться в архитектуре системы на такое требование: в таких таблицах вообще не должно происходить апдейтов, а вот инсерты пойдут просто непрерывным потоком - новая версия будет означать новую запись в таблице. При этом ничего не будет переписываться, взаимоблокироваться, дэдлочиться и т.д. :evil: Ну разве что индексы на первичных ключах...

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 22.03.2005 (Вт) 8:19

Krasavica писал(а):На самом деле это большая проблема - одна из её ветвей потерянные обновления: например пользователь 1 и 2 обратились к записи в состоянии 1. Потом пользователь 1 изменил запись и перевёл её в состояние 2, после этого пользователь 2 изменил запись и перевёл её в состояние 3. В результате изменения внесённые пользователем 1 были утеряны.


Вообще-то, если разные пользователи меняли в записи разные поля, то сохранятся изменения всех пользователей. Это при работе с Recordset-ом классического ADO. В NET, с его DatSet-ами и его системой обработки, сохранится только запись последнего пользователя.
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 22.03.2005 (Вт) 8:41

И мои пять копеек :)
Сообщение о том, что запись блокирована, появляется, когда два пользователя пытаются сделать что-то с записью одновременно. При этом, что именно подразумевается под одновременностью, определяется типом блокировки.
При пессиместической блокировке запись блокируется с момента начала редактирования (.Edit) и до момента завершения обновления записи (.Update). При оптимистической блокировке запись блокируется при начале обновления записи и до момента завершения обновления.
Lasciate ogni speranza, voi ch'entrate.


Вернуться в Базы данных

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3

    TopList