Автор | Сообщение |
|
| постоянный участник
|
Пост N: 1091
Зарегистрирован: 27.01.07
|
|
Отправлено: 11.07.15 10:37. Заголовок: А работает ли механизм транзакций letodb
в udf-функциях?
|
|
|
Новых ответов нет
, стр:
1
2
3
All
[см. все]
|
|
|
| Администратор
|
Пост N: 3381
Зарегистрирован: 23.05.05
|
|
Отправлено: 18.12.15 13:48. Заголовок: Все равно у меня не ..
Все равно у меня не получается медленная транзакция Без транзакции результат 24.65 сек С транзакцией: 4.96 сек Служба letodb установлена на компьютере с win7 letodb.ini: DataPath = e:/ EnableFileFunc = 1 EnableAnyExt = 1 Optimize = 1 AutOrder = 1 Default_Driver = NTX #Share_Tables = 1 Вот мой тест: PROC Main Local cPath, nSec, i, nn := 0 Local cNm := 'doma' Local lTr := .t. Field Code, OCATD, GNINMB, ID, Name request leto, DBFCDX RddSetDefault ("LETO") cPath := "//10.0.0.1:2812/" //cPath := "//127.0.0.1:2812/" Leto_Connect (cPath) USE (cPath + cNm) alias db_srv SHARED NEW if ! leto_File(cPath+cNm+'1.ntx') ? 'Indexing...' index on ID to doma1 index on Upper(NAME) to doma2 index on ID to doma3 endif SET INDEX TO (cPath + cNm + '1') additive SET INDEX TO (cPath + cNm + '2') additive SET INDEX TO (cPath + cNm + '3') additive dbSetOrder(1) use (cNm) alias db_loc new via "DBFCDX" go top nSec := Seconds() if lTr db_srv->(leto_BeginTransaction(32768)) endif while ! eof() db_srv->(dbAppend()) for i := 1 to fcount() db_srv->(FieldPut(i, db_loc->(FieldGet(i)))) next if nn % 10000 == 0 ? nn if lTr db_srv->(leto_CommitTransaction()) db_srv->(leto_BeginTransaction(32768)) endif endif if ++nn == 15000 exit endif skip enddo if lTr db_srv->(leto_CommitTransaction()) endif ? lTr, Seconds() - nSec RETURN
|
|
|
|
| |
Пост N: 53
Зарегистрирован: 06.05.14
|
|
Отправлено: 24.12.15 05:08. Заголовок: Очень странно. Паша,..
|
|
|
|
| постоянный участник
|
Пост N: 4628
Зарегистрирован: 12.09.06
|
|
Отправлено: 24.12.15 12:02. Заголовок: nbatocanin пишет: ч..
nbatocanin пишет: цитата: | чтобы попробовать программу |
| Попробовал. Сервер в инете Win2008, вот результат: Indexing... 0 10000 .F. 322.13 Indexing... 0 10000 .T. 2.36
|
|
|
|
| |
Пост N: 54
Зарегистрирован: 06.05.14
|
|
Отправлено: 05.01.16 20:31. Заголовок: Есть ли функция Leto..
Есть ли функция Leto_CommitTransaction выполняет COMMIT? Необходимо ли выполнить COMMIT после Leto_CommitTransaction? Ненад
|
|
|
|
| Администратор
|
Пост N: 3401
Зарегистрирован: 23.05.05
|
|
Отправлено: 06.01.16 08:03. Заголовок: COMMIT желательно де..
COMMIT желательно делать до выполнения Leto_CommitTransaction()
|
|
|
|
| |
Пост N: 55
Зарегистрирован: 06.05.14
|
|
Отправлено: 08.01.16 05:49. Заголовок: Я сделал новые тесты..
Я сделал новые тесты на несколько серверов (10+). Сначала я попробовал тест, который сделал Паша. Результаты (для меня) были очень странные. Время выполнения очень меняется (почему я взял среднее значение из нескольких тестов). На некоторых серверах, программа выполняется быстрее без транзакции, но в некоторых наоборот. Я думаю, время зависит от скорости диска и Windows кэширования. Например, тест на одном сервере с двумя дисками (HDD и SSD): Tran NoTr --------------- HDD 3.9 1.1 SDD 1.4 1.8 Но этот тест не выполняют COMMIT в конце программы, так что я сделал новый тест, который использует функцию Leto_Commit(): IF lTrans Leto_CommitTransaction() END IF Leto_Commit() Я также сделал тест так, чтобы больше соответствовать реальной ситуации. Вот тестовая программа: GoogleDrivehttps://drive.google.com/open?id=0BwEGIJ1QfjrKT2RLdlNvV2NwUHc Новый тест показал, что работать с транзакции (+COMMIT) всегда быстрее, чем без: Tran NoTr --------------- S1 2.5 8.2 S2 1.1 5.6 S3 4.6 10.6 S4 1.1 0.8 Исключением является сервер с SSD (S4).
|
|
|
|
| |
Пост N: 56
Зарегистрирован: 06.05.14
|
|
Отправлено: 08.01.16 20:24. Заголовок: Как ускорить транза..
Как ускорить транзакциу, которая имеет команду DELETE?. Например: Leto_BeginTransaction() // SEEK nOldId WHILE nOldId == d_id DELETE SKIP END DO // ... // Leto_CommitTransaction() Эта программа работает в 20 раз быстрее без транзакции. Программа исключить около 25.000 записей.
|
|
|
|
| |
Пост N: 5458
Зарегистрирован: 17.05.05
|
|
Отправлено: 08.01.16 22:31. Заголовок: nbatocanin пишет: W..
nbatocanin пишет: Про ускорение не скажу а вот код надо подправить. IF DBSEEK( nOldId ) WHILE nOldId == d_id .and. !eof() DELETE SKIP END DO ENDIF Хотя можно ускорить так (без проверки ключа) IF DBSEEK( nOldId ) dbOrderInfo(DBOI_SCOPEBOTTOM,,,nOldId)) DO WHILE !eof() DELETE SKIP END DO dbOrderInfo(DBOI_SCOPEBOTTOMCLEAR) ENDIF
|
|
|
|
| |
Пост N: 57
Зарегистрирован: 06.05.14
|
|
Отправлено: 09.01.16 05:19. Заголовок: Попробовал, но не им..
Попробовал, но не имеют никакого эффекта. Я также попробовал DELETE WHILE. Без транзакции: 1.67 С транзакцией: 80.00
|
|
|
|
| Администратор
|
Пост N: 3402
Зарегистрирован: 23.05.05
|
|
Отправлено: 10.01.16 09:51. Заголовок: nbatocanin пишет: К..
nbatocanin пишет: цитата: | Как ускорить транзакциу, которая имеет команду DELETE?. Например: Leto_BeginTransaction() // SEEK nOldId WHILE nOldId == d_id DELETE SKIP END DO // ... // Leto_CommitTransaction() Эта программа работает в 20 раз быстрее без транзакции. Программа исключить около 25.000 записей. |
| Немного видоизмените алгоритм: Leto_BeginTransaction() // i := 0 SEEK nOldId WHILE nOldId == d_id DELETE i ++ if i%1000 == 0 Leto_CommitTransaction() Leto_BeginTransaction() endif SKIP END DO Leto_CommitTransaction() Причина замедления транзакции для большого количества записей следующая: после получения новых данных с сервера по команде skip выполняется проверка, есть ли новая полученная запись в данных транзакции. Если запись есть, то она формируется по данным из буфера транзакции. После каждой итерации буфер транзакции увеличивается, и проверка выполняется каждый раз медленнее. В этом случае такая проверка и не нужна, поскольку новая запись заведомо не присутствует в буфере транзакции, но в общем случае она нужна.
|
|
|
|
| |
Пост N: 58
Зарегистрирован: 06.05.14
|
|
Отправлено: 10.01.16 20:48. Заголовок: Спасибо Пашa, это ча..
Спасибо Пашa, это частично решило проблему. Но программа без транзакции по-прежнему работает быстрее (4.5sek; Без: 1.5сек). Можно ли как-то исключить эту проверку?
|
|
|
|
|
| |
Пост N: 60
Зарегистрирован: 06.05.14
|
|
Отправлено: 09.04.16 16:39. Заголовок: Pasha пишет: Причин..
Pasha пишет: цитата: | Причина замедления транзакции для большого количества записей следующая: после получения новых данных с сервера по команде skip выполняется проверка, есть ли новая полученная запись в данных транзакции. Если запись есть, то она формируется по данным из буфера транзакции. После каждой итерации буфер транзакции увеличивается, и проверка выполняется каждый раз медленнее. В этом случае такая проверка и не нужна, поскольку новая запись заведомо не присутствует в буфере транзакции, но в общем случае она нужна. |
| Паша, можно ли как-то выключение этой проверки? У меня есть большие транзакции, в которых нет дубликатов. Спасибо, Ненад
|
|
|
|
| Администратор
|
Пост N: 3426
Зарегистрирован: 23.05.05
|
|
Отправлено: 11.04.16 08:15. Заголовок: Сегодня вечером сдел..
Сегодня вечером сделаю обновление
|
|
|
|
| постоянный участник
|
Пост N: 934
Зарегистрирован: 17.02.12
|
|
Отправлено: 11.04.16 14:09. Заголовок: Pasha В старой верс..
Pasha В старой версии leto (клиент), мы сделали (стало надежнее, стабильнее): static BOOL lNewCritSect=TRUE; CRITICAL_SECTION CritSect; #define CS_EN() EnterCriticalSection( &CritSect ) #define CS_LV() LeaveCriticalSection( &CritSect ) long int leto_DataSendRecv( LETOCONNECTION * pConnection, const char * sData, ULONG ulLen ) { long int n = 0; if( lNewCritSect ) { InitializeCriticalSectionAndSpinCount(&CritSect, 0x00000400); // TryEnterCriticalSection( &CritSect ); lNewCritSect = FALSE; } CS_EN(); if( hb_ipSend( pConnection->hSocket, sData, (ulLen)? ulLen:strlen(sData), -1 ) > 0 ) { n = leto_Recv( pConnection->hSocket ); // return 0; } CS_LV(); // return leto_Recv( pConnection->hSocket ); return n; } в новой также планируем сделать, пока на новой не работаем (только тестируем)
|
|
|
|
| постоянный участник
|
Пост N: 935
Зарегистрирован: 17.02.12
|
|
Отправлено: 11.04.16 18:16. Заголовок: PS что то я с раздел..
PS что то я с разделом промахнулся - это (выше) к "Internal Error" относиться. Sory
|
|
|
|
| |
Пост N: 62
Зарегистрирован: 06.05.14
|
|
Отправлено: 12.04.16 16:34. Заголовок: long int leto_DataSe..
цитата: | long int leto_DataSendRecv( LETOCONNECTION * pConnection, const char * sData, ULONG ulLen ) |
| Можете ли вы объяснить, что делает эта функция?
|
|
|
|
| постоянный участник
|
Пост N: 939
Зарегистрирован: 17.02.12
|
|
Отправлено: 12.04.16 17:17. Заголовок: nbatocanin пишет:что..
nbatocanin пишет: как я понимаю, она посылает команды серверу и ждет их выполнения
|
|
|
|
| |
Пост N: 63
Зарегистрирован: 06.05.14
|
|
Отправлено: 13.04.16 03:54. Заголовок: Pasha пишет: Сегодн..
Pasha пишет: цитата: | Сегодня вечером сделаю обновление |
| работает, спасибо!
|
|
|
|
| |
Пост N: 98
Зарегистрирован: 06.05.14
|
|
Отправлено: 12.07.16 03:46. Заголовок: Почему это не работа..
Почему это не работает? USE Test NEW Leto_BeginTransaction () s := Select() FLock() (s)->(DBUnlock()) // Syntax error Leto_CommitTransaction ()
|
|
|
|
| Администратор
|
Пост N: 3463
Зарегистрирован: 23.05.05
|
|
Отправлено: 12.07.16 11:50. Заголовок: Во время транзакции ..
Во время транзакции нельзя выдавать dbUnlock() Надо или разблокировать данные после LETO_COMMITTRANSACTION(). либо выдать LETO_COMMITTRANSACTION(.t.), задав параметр lUnlockAll
|
|
|
Новых ответов нет
, стр:
1
2
3
All
[см. все]
|
|