-Поиск по дневнику

Поиск сообщений в rss_sql_ru_access_programming

 -Подписка по e-mail

 

 -Постоянные читатели

 -Статистика

Статистика LiveInternet.ru: показано количество хитов и посетителей
Создан: 16.03.2006
Записей:
Комментариев:
Написано: 4


БД Accees 2013 .accdb, непомерный рост сетевого трафика при кол-ве пользователей >1

Пятница, 25 Марта 2016 г. 11:57 + в цитатник
Всем хорошего дня!

Есть БД (таблицы с данными и несколько запросов) на файл-сервере. Формат Access 2007-2013 .accdb.

Пользователи присоединяются к базе через интерфес Excel с и использованием ADODB. Часть запросов храниться в виде хард-кода на VBA, часть внутри БД.

Выполнение одних и тех же действий, когда к базе подключен 1 пользователь и когда более различается как 20 сек и 3 мин. Может быть дело в типах блокировки или свойствах курсора соединения, но способа лечения не нашел.
Ниже приложу картинки с сетевым трафиком (там видно, что для 2-х пользователей кол-во передаваемых по сети данных превышает объем БД, хранящейся на файл-сервере - сейчас это 9 МБ).

Вот перечень операций (макс обновление на 400 записей), которые выполняются и в том и другом случае:

transaction_level = SMART_CNN.Cnn.BeginTrans


    '*************************************** _
'РАСЧЕТ Абонентской базы
SQL_query = "SELECT bld_params.* " _
    & "FROM bld_params INNER JOIN Buildings ON bld_params.ID_SU = Buildings.ID_SU WHERE Buildings.Processed=0 " _
    & "ORDER BY bld_params.ID_SU, bld_params.Life_Time;"
Aab_Tkd_RS.CursorType = adOpenKeyset
Aab_Tkd_RS.Open SQL_query, SMART_CNN.Cnn, adOpenKeyset, adLockOptimistic
With Aab_Tkd_RS
    'редактируем рекордсет ~ 400 записей
         предыдущее_значение=![Поле1]
         if(предыдущее_значение<>"") then
               ![Поле1]=![Поле1]*предыдущее_значение*коэффициент_какой-то
         endif
        .Update
        .MoveNext
    Loop
End With
'если что-то пойдет не так то выполнится
If (rez <> "OK") Then
        BasicFunctions.UserDataDisplayError (rez & vbNewLine & "Изменения в модели будут отменены!")
        SMART_CNN.Cnn.RollbackTrans
        GoTo ExecExit
End If
    '***************************************
Aab_Tkd_RS.Close
    
    '*************************************** _
    РАСЧЕТ OPEX
    SQL_query = "DELETE * FROM opex " _
        & "WHERE data_id in (SELECT data_id FROM bld_params WHERE Processed=0);"
    SMART_CNN.Cnn.Execute SQL_query, adExecuteNoRecords, dbFailOnError 'УБИРАЕМ ПРЕДЫДУЩИЕ ДАННЫЕ

SQL_query="UPDATE еще 400 записей"
SMART_CNN.Cnn.Execute SQL_query, adExecuteNoRecords, dbFailOnError
    If (rez <> "OK") Then
        BasicFunctions.UserDataDisplayError (rez & vbNewLine & "Изменения в модели будут отменены!")
        SMART_CNN.Cnn.RollbackTrans
        GoTo ExecExit
    End If
    BasicFunctions.WriteIntoLog 22, "Кол-во домов: " & bld_counter
    '***************************************
    
PrDisplayer.Recharge

    '*************************************** _
    РАСЧЕТ CAPEX
    SQL_query="UPDATE еще 400 записей"
    SMART_CNN.Cnn.Execute SQL_query, adExecuteNoRecords, dbFailOnError
    If (rez <> "OK") Then
        BasicFunctions.UserDataDisplayError (rez & vbNewLine & "Изменения в модели будут отменены!")
        SMART_CNN.Cnn.RollbackTrans
        GoTo ExecExit
    End If
    BasicFunctions.WriteIntoLog 23, "Кол-во домов: " & bld_counter
    '***************************************
    
    
    '*************************************** _
    РАСЧЕТ ВЫРУЧКИ
    SQL_query = "DELETE * FROM Revenue_Profits WHERE data_id in (SELECT data_id FROM bld_params WHERE Processed=0);"
    SMART_CNN.Cnn.Execute SQL_query, adExecuteNoRecords, dbFailOnError 'УБИРАЕМ ПРЕДЫДУЩИЕ ДАННЫЕ
    rez = ProcessRevenueAndProfits(PrDisplayer)'функция открывает рекордсет и редактирует 400 записей, _ 
'так же, как это выполняется в части кода РАСЧЕТ Абонентской базы
    If (rez <> "OK") Then
        BasicFunctions.UserDataDisplayError (rez & vbNewLine & "Изменения в модели будут отменены!")
        SMART_CNN.Cnn.RollbackTrans 
        GoTo ExecExit
    End If
    BasicFunctions.WriteIntoLog 24, "Кол-во домов: " & bld_counter
    '***************************************

    
    '*************************************** _
    РАСЧЕТ Cash Flow
    SQL_query = "DELETE * FROM CashFlow WHERE data_id in (SELECT data_id FROM bld_params WHERE Processed=0);"
    SMART_CNN.Cnn.Execute SQL_query, adExecuteNoRecords, dbFailOnError 'УБИРАЕМ ПРЕДЫДУЩИЕ ДАННЫЕ
    SMART_CNN.Cnn.Execute "CF_data", adExecuteNoRecords, dbFailOnError 'СЧИТАЕМ CF
    BasicFunctions.WriteIntoLog 25, "Кол-во домов: " & bld_counter
    '***************************************
    
'ФИНАЛИЗАЦИЯ РАСЧЕТА
SMART_CNN.Cnn.Execute "UPDATE bld_params SET Processed=1 WHERE Processed=0;", adExecuteNoRecords, dbFailOnError
SMART_CNN.Cnn.Execute "UPDATE buildings SET Processed=1 WHERE Processed=0;", adExecuteNoRecords, dbFailOnError

SMART_CNN.Cnn.CommitTrans
BasicFunctions.WriteIntoLog 27, "Домов: " & bld_counter
'***************************************

При запуске Excel на стороне пользователя происходит соединение с БД:
Public DataWorkBook As Excel.Workbook
Public Log_CNN As SmartCnn 'соединение с лог-файлом
Public SMART_CNN As SmartCnn 'соединение с лог-файлом
Public MyUser As SMART_User
Public SMART_Exec As SMART_Extractor
Public SMART_Ribbon As IRibbonUI
Public button_enable_state As Boolean
#If VBA7 And Win64 Then
    ' 64 битный Excel
    Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongLong)
    Public Declare PtrSafe Function timeGetTime Lib "winmm.dll" () As Long
#Else
    ' 32 битный Excel
    Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    Public Declare Function timeGetTime Lib "winmm.dll" () As Long
#End If
Function Init() As Boolean 'запускаем все нужные соединения и классы объектов перед работой

Dim cnn_string As String
Dim MySmartCnn As SmartCnn

    Set MyUser = New SMART_User 'СОЗДАЕМ ПОЛЬЗОВАТЕЛЯ, ПОЛУЧАЕМ СЕТЕВОЙ ЛОГИН
    button_enable_state = True 'по умолчанию все элементы ленты активны
    If (ActiveWorkbook Is Nothing) Then
        Exit Function
    End If
    
    Set DataWorkBook = ActiveWorkbook
    
    If Not (BasicFunctions.CheckFilePath(SMART_DB_PATH & "\" & SMART_DB_NAME)) Then
        MsgBox "Не найден файл базы данных SAMRT", vbCritical, "SMART processor"
        Init = False
        Exit Function
    End If
    
    If Not (BasicFunctions.CheckFilePath(SMART_DB_PATH & "\" & LOG_DB_NAME)) Then
        MsgBox "Не найден файл базы данных ведения лога", vbCritical, "SMART processor"
        Init = False
        Exit Function
    End If
    
    'ОПРЕДЕЛЯЕМ РАЗМЕЩЕНИЕ ВРЕМЕННОЙ БД
    user_tmp_db_path = Application.DefaultFilePath

    '*************************************** _
    ПОДКЛЮЧЕНИЕ ЛОГ - ФАЙЛА
    Set Log_CNN = New SmartCnn

    cnn_string = "Provider=Microsoft.ACE.OLEDB.12.0;" _
    & "Data Source=" & SMART_DB_PATH & "\" & LOG_DB_NAME & ";" _
    & "Jet OLEDB:Database Password=********;"
    If Not (Log_CNN.CreateADOConnectionToDB(cnn_string)) Then
        MsgBox "Не удалось подключиться к базе данных LOGa.", vbCritical, "SMART processor"
        Init = False
    End If
    '***************************************
    
    '*************************************** _
    ПОДКЛЮЧЕНИЕ ФАЙЛА БАЗЫ ДАННЫХ
    Set SMART_CNN = New SmartCnn
    cnn_string = "Provider=Microsoft.ACE.OLEDB.12.0;" _
    & "Data Source=" & SMART_DB_PATH & "\" & SMART_DB_NAME & ";" _
    & "Jet OLEDB:Database Password=*********;"
    If Not (SMART_CNN.CreateADOConnectionToDB(cnn_string)) Then
        MsgBox "Не удалось подключиться к базе данных SMART.", vbCritical, "SMART processor"
        Init = False
        Exit Function
    End If
    '***************************************
    
    MyUser.CheckUp (MyUser.WinName)
    'MyUser.CheckUp ("Lis")
    If Not (MyUser.ValidUser) Then
        BasicFunctions.UserDataDisplayError ("У пользователя " & MyUser.WinName & " нет доступа к SMART-модели.")
        Init = False
        Exit Function
    End If
    If (MyUser.Status = "Deleted") Then
        BasicFunctions.UserDataDisplayError ("Ууу разбойник! Пользователю " & MyUser.WinName & vbCrLf _
        & " доступ к SMART-модели заблокирован.")
        Init = False
        Exit Function
    Else
        MyUser.SetCurrentCompName
    End If
    
BasicFunctions.WriteIntoLog 1

Init = True

Exit Function

End Function


Код класса SmartCnn:
Public WithEvents Cnn As ADODB.Connection
Private start_exec_time As Long 'в миллисекундах
Private exec_time As Long 'в миллисекундах
Private exec_timeout As Long 'в секундах
Private Sub Class_Initialize()
    Set Me.Cnn = New ADODB.Connection
    Me.Cnn.CursorLocation = adUseClient
    exec_timeout = SMART_EXEC_TIMEOUT
End Sub
Public Function CreateADOConnectionToDB(cnn_string As String) As Boolean
    
    On Error GoTo ErrHandler

    Me.Cnn.Open cnn_string, "Admin", , adConnectUnspecified
    CreateADOConnectionToDB = True
    Exit Function
    
ErrHandler:
    'BasicFunctions.RaiseError 514
    If (Err.Number = 3705) Then
        MsgBox Err.Description
        CreateADOConnectionToDB = False
        Exit Function
    End If
    BasicFunctions.DisplayError
End Function
Private Sub Cnn_ExecuteComplete(ByVal RecordsAffected As Long, ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, ByVal pCommand As ADODB.Command, ByVal pRecordset As ADODB.Recordset, ByVal pConnection As ADODB.Connection)
    exec_time = BasicFunctions.timeGetTime - start_exec_time
End Sub
Private Sub Cnn_WillExecute(Source As String, CursorType As ADODB.CursorTypeEnum, LockType As ADODB.LockTypeEnum, Options As Long, adStatus As ADODB.EventStatusEnum, ByVal pCommand As ADODB.Command, ByVal pRecordset As ADODB.Recordset, ByVal pConnection As ADODB.Connection)
    start_exec_time = BasicFunctions.timeGetTime
    exec_time = 0
End Sub
Public Property Get ExecTime() As Long
    ExecTime = exec_time
End Property
Public Sub CheckExecTimeout()

    If (exec_time <> 0) Then Exit Sub
    If (((BasicFunctions.timeGetTime - start_exec_time) / 1000) > exec_timeout) Then
        BasicFunctions.UserDataDisplayError "Превышен лимит времени в " & exec_timeout & " секунд при привыполнении запроса к модели."
        Me.Cnn.Cancel
    End If

End Sub

Не смотря на то, что устанавливаю свойство соединения
Me.Cnn.CursorLocation = adUseClient
, когда в RunTime смотрю на объект SMART_CNN.Cnn у него это свойство поставлено в adUseClientBatch
Гуру, help plase.

http://www.sql.ru/forum/1206894/bd-accees-2013-accdb-nepomernyy-rost-setevogo-trafika-pri-kol-ve-polzovateley-1


 

Добавить комментарий:
Текст комментария: смайлики

Проверка орфографии: (найти ошибки)

Прикрепить картинку:

 Переводить URL в ссылку
 Подписаться на комментарии
 Подписать картинку