Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Трабла с транзакциями / 9 сообщений из 9, страница 1 из 1
14.09.2006, 13:14
    #33986877
Nikz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Трабла с транзакциями
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
Option Explicit
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private c1 As New ADODB.Connection
Private c2 As New ADODB.Connection
Private r1 As New ADODB.Recordset
Private r2 As New ADODB.Recordset
Private Sub Form_Load()
c1.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\base.mdb;Persist Security Info=False"
c2.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\base.mdb;Persist Security Info=False"
r1.Open "SELECT * FROM table1", c1, adOpenDynamic, adLockOptimistic
r2.Open "SELECT * FROM table1", c2, adOpenDynamic, adLockOptimistic
c1.BeginTrans
c2.BeginTrans
End Sub
Private Sub Command1_Click()
r1.AddNew
r1.Update
End Sub
Private Sub Command2_Click()
r2.AddNew
r2.Update
End Sub
собственно вот такой код (упрощенно)
идея в том что:
есть два места в программе которые работают с одной и той же таблицей
из этих двух мест может производиться добавление, удаление и редактирование записей.
Код: plaintext
1.
2.
c1.BeginTrans
c2.BeginTrans
используются для того, что бы изменения попадали в табличку не сразу, а только после того как пользователь нажмет на кнопку "Сохранить", тогда в зависимости от того в какой части программы она была нажата произойдет
Код: plaintext
1.
2.
c1.CommitTrans
c1.BeginTrans
или
Код: plaintext
1.
2.
c2.CommitTrans
c2.BeginTrans
т.е. применяем изменения и начинаем слушать новые изменения, что бы потом опять сохранить их (или не сохранять)

так вот, проблема в том, что если сначала выполнить
Код: plaintext
1.
2.
3.
4.
Private Sub Command1_Click()
r1.AddNew
r1.Update
End Sub
то потом, при попытке выполнить
Код: plaintext
1.
2.
3.
4.
Private Sub Command2_Click()
r2.AddNew
r2.Update
End Sub
возникает мессадж
"Could not update, currently locked"
в принципе это логично, началась транзакция, и база заблокировалась для изменений, что бы не допустить возможность ошибки...
НО
обработку возможных inconsistence я беру на себя
поэтому, уважаемый ALL может быть ты знаешь какой то способ как то ее обмануть???

или может быть я делаю все через з... и есть какой то более простой способ реализовать такую штуку:
пользователь правит данные
но изменения не записываются в базу
и ТОЛЬКО после того как юзер дал комманду сохранить, инфа в базе бы обновилась
?
...
Рейтинг: 0 / 0
14.09.2006, 13:29
    #33986977
Melkiades
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Трабла с транзакциями
Мда. Открывать вот так транзакции - самый плохой вариант здесь. Накапливайте информацию о произведенных юзером изменениях в клиентском приложении, и только в момент нажатия кнопки "сохранить" открывайте транзакцию и производите все эти изменения в БД. Правда, понадобится проверять актуальность сохраняемых данных - вдруг, когда пользователь их правил, другой их уже пересохранил. Но это вопрос бизнес-логики, и вам должно быть виднее, дожно здесь быть FIFO или не должно.
...
Рейтинг: 0 / 0
14.09.2006, 13:59
    #33987148
Nikz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Трабла с транзакциями
ну это вариант и раньше было сделано так:
никаких транзакций
инфа из рекордсета заносилась в listview
затем когда поработали с listview и нажимали "Сохранить" было сделано приблизительно так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
Private Sub save_changes()
Dim tempR As New ADODB.Recordset
Dim i As Integer
For i =  1  To List.IistItems.Count
    If List.ListItems(i).Tag = "Y" Then
        'удаление удаленных
        c1.Execute "DELETE * FROM table1 where table1.ID = " & List.ListItems(i).Text 'IF Tag is "Y" then record must be deleted
    Else
        'проверка новая запись или нет
        tempR.Open "SELECT table1.ID FROM table1 WHERE table1.ID = " & List.ListItems(i).Text, c1
        If tempR.EOF Then
            'новая запись, есть в ListView но нет в рекордсете
            'тогда добавляем в базу
            c1.Execute "INSERT INTO table1 (FULLNAME) SELECT '" & List.ListItems(i).ListSubItems( 1 ).Text & "'"
        Else
            'запись есть в базе
            c1.Execute "UPDATE table1 set table1.FULLNAME = '" & List.ListItems(i).ListSubItems( 1 ).Text & "' WHERE table1.ID = " & List.ListItems(i).Text
        End If
        tempR.Close
    End If
Next i
End Sub
НО
при наличии в рекордсете, например 10000 записей, обработка растягивается на очень, очень большое время, поэтому от этого пришлось отказаться
тогда я и стал искать способ сделать так, что бы при изменении каждой строки инфа попадала в базу, и потом можно было просто применить изменения
и пока остановился на транзакциях (хоть и плохая это идея, согласен)
вот я и думаю, может есть какой то способ завести что то типа "виртуального рекордсета" и потом одной командой сделать ему синхронизацию с базой
?
...
Рейтинг: 0 / 0
14.09.2006, 15:06
    #33987541
Melkiades
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Трабла с транзакциями
А зачем проверять на изменения все 10000 записей? Заведите отдельную коллекцию (или массив), куда добавляйте только изменные элементы. И ее сохраняйте.
...
Рейтинг: 0 / 0
14.09.2006, 15:51
    #33987785
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Трабла с транзакциями
А чем не устраивает обычный отсоединенный рекордсет? Или автор о таком не знает? Будь там хоть 100000 записей, апдейтом будут обработаны только измененные и это не займет много времени.
...
Рейтинг: 0 / 0
14.09.2006, 16:07
    #33987879
Nikz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Трабла с транзакциями
AntonariyА чем не устраивает обычный отсоединенный рекордсет? Или автор о таком не знает? Будь там хоть 100000 записей, апдейтом будут обработаны только измененные и это не займет много времени.
стыдно,
автор о таком не знает...
а как это изобразить, если в двух словах?
или может ссылку какую, если двух словах не получится...
...
Рейтинг: 0 / 0
14.09.2006, 16:20
    #33987946
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Трабла с транзакциями
Получится. =)
cn.CursorLocation = adUseClient 'означает, что сразу все записи выборок будут отдаваться клиенту
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
cn.Open 
rs.Open "select", cn, adOpenStatic, adLockBatchOptimistic
Set rs.ActiveConnection = Nothing 'в принципе "отсоединять" нужно только в трехзвенном приложении

'работаем с рекордсетом

Set rs.ActiveConnection = cn
cn.BeginTrans 'тоже не обязательно, если апдейтится только один рекордсет за раз
rs.Updatebatch
cn.CommitTrans
...
Рейтинг: 0 / 0
14.09.2006, 16:23
    #33987959
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Трабла с транзакциями
Факин шит нихт правка ин дас форум((
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
cn.CursorLocation = adUseClient 'означает, что сразу все записи выборок будут отдаваться клиенту

cn.Open 
rs.Open "select", cn, adOpenStatic, adLockBatchOptimistic
Set rs.ActiveConnection = Nothing 'в принципе "отсоединять" нужно только в трехзвенном приложении

'работаем с рекордсетом

Set rs.ActiveConnection = cn
cn.BeginTrans 'тоже не обязательно, если апдейтится только один рекордсет за раз
rs.Updatebatch
cn.CommitTrans
...
Рейтинг: 0 / 0
14.09.2006, 16:30
    #33987993
Nikz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Трабла с транзакциями
AntonariyПолучится. =)
...
кРРРуто!
спасибо, то что надо
как грится:
век живи - век учись :)
...
Рейтинг: 0 / 0
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Трабла с транзакциями / 9 сообщений из 9, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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