On-line: гостей 2. Всего: 2 [подробнее..]
АвторСообщение
постоянный участник


Пост N: 1091
Зарегистрирован: 27.01.07
ссылка на сообщение  Отправлено: 11.07.15 10:37. Заголовок: А работает ли механизм транзакций letodb


в udf-функциях?

Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 44 , стр: 1 2 3 All [только новые]


Администратор




Пост N: 3313
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 11.07.15 14:51. Заголовок: Увы, нет. Механизм т..


Увы, нет. Механизм транзакции таков: все изменения накапливаются на клиенте без передачи на сервер, и только по LETO_COMMITTRANSACTION пакетом передаются на сервер, где и выполняются.
Поскольку вызовы leto_udf сразу передаются на сервер и сразу выполняются, вписать их в механизм транзакций не представляется возможным.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 1092
Зарегистрирован: 27.01.07
ссылка на сообщение  Отправлено: 11.07.15 15:06. Заголовок: Жаль. Подумалось, чт..


Жаль. Подумалось, что было бы неплохо использовать свойство транзакции "либо выполняется целиком, либо не выполняется вообще" при записи из udf-функции, но, видимо, там уже напрямую работает rdd и "влезть" в этот процесс без переделки rdd не получится. Спасибо.

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 43
Зарегистрирован: 06.05.14
ссылка на сообщение  Отправлено: 22.11.15 23:49. Заголовок: Команда Leto_BeginTr..


Команда Leto_BeginTransaction() работает, только если DBF открыт с LetoDB. Например, это не работает:

USE Test VIA "DBFNTX" NEW
Leto_BeginTransaction() // Syntax error

Почему? Это очень неудобно для универсальной процедурой которая копирует записи из локального DBF на сервер.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 172
Зарегистрирован: 15.09.05
ссылка на сообщение  Отправлено: 23.11.15 10:05. Заголовок: С транзакциями надо соблюдать следующие правила


С транзакциями надо соблюдать следующие правила :
1. Использовать их только в зонах действия RDD "LETO" , другими словами после RDDSETDEFAULT( "LETO" )
а потом для взаимодействия между файлми разных RDD использовать алиасное имя
2. До закрытия транзакции нельзя использовать команду COMMIT. ( получится Sintax error)

Может Паша посоветует еще чего то .

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 3360
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 23.11.15 11:23. Заголовок: Надо просто вызывать..


Надо просто вызывать Leto_BeginTransaction() с рабочей областью, открытой через leto
Пример:

letotab->( Leto_BeginTransaction() )

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 44
Зарегистрирован: 06.05.14
ссылка на сообщение  Отправлено: 23.11.15 18:59. Заголовок: Я знаю, что это може..


Я знаю, что это может решить проблему, но мне интересно, почему Leto_BeginTransaction() использует открытый DBF? Объяснение: в программе у меня есть следующие части:


 цитата:
SELECT Tmp
TransBegin()

WHILE !Eof()
TransProc()
LetoTab->(DBAppend())
LetoTab->f1 := f1
LetoTab->f2 := f2
...
SKIP
END DO
TransEnd()



Универсальные функции (TransBegin, TransProc и TransEnd) хочу, чтобы использовать во всей программы. Функция TransBegin на основе записи TMP (DBFNTX) устанавливает параметры и призывает Leto_BeginTransaction. Но TransBegin "не знает" за LetoTab, поэтому я вынужден передать и этот параметр. Вот почему я хочу знать, если он играет роль в Leto_BeginTransaction?

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 3363
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 24.11.15 08:04. Заголовок: Такое поведение связ..


Такое поведение связано с тем, что функции Leto_BeginTransaction необходимо знать, для какого соединения (сервера) letodb будет транзакция. Соединений же может быть несколько. Вот это соединение и берется из текущей рабочей области. А если эта р/о не leto, то генерируется ошибка.

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 45
Зарегистрирован: 06.05.14
ссылка на сообщение  Отправлено: 24.11.15 22:20. Заголовок: Спасибо! Я буду испо..


Спасибо! Я буду использовать любую открытую DBF.

(Это не имеет большое значения, но я думаю, что это должно быть изменено).



Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 46
Зарегистрирован: 06.05.14
ссылка на сообщение  Отправлено: 29.11.15 00:33. Заголовок: Когда я начал исполь..


Когда я начал использовать транзакции, моя программа начала работать гораздо медленнее. Так что я сделал некоторые тесты. Тестовая программа копирует локальный DBF в таблице на сервере. Я обнаружил, что моя программа работает намного медленнее, чем Андреев DbfToServer. Например, таблицы 30000 записей:

DbfToServer: 11 с
моя программа: 65 с

Чтобы скопировать, используя тот же алгоритм. После многих испытаний, я нашел разницу: моя DBF таблицы на сервере имеет индекс. Когда индекс выключен, программа значительно ускоряется. Это нормально, LetoDB требуется больше времени, чтобы обновить индекс. Но когда выключается транзакции, программа становится в несколько раз быстрее: 19 с! Почему? Это не логично.

Тогда я попытался изменить размер буфера для транзакции. Я обменял буфер от 1000 до 50.0000, но я не заметил существенной разницы в скорости. Лучшие результаты имеют для буфера 3000-4000. DbfToServer определять размер буфера 1000 x RecordSize, но использует только 70%. Например, если размера данных 1500, тогда буфер 1.500.000, что я думаю, это слишком много.

Что бы вы посоветовали?


Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 47
Зарегистрирован: 06.05.14
ссылка на сообщение  Отправлено: 04.12.15 05:30. Заголовок: Продолжаю тестирован..


Продолжаю тестирования с индексами. Я сделал программу, которая копирует Test0 DBF (10000 записей) с локального диска на сервер в DBF Test2. Копирование выполняется следующим образом:

1. Тест2 не имеет индексов, без транзакции (-)
2. Тест2 имеет индексы, без транзакции (I)
3. Тест2 не имеет индексы, транзакции включены (T)
4. Тест2 имеет индексы, транзакции включены (I+T)

Программа и результаты можно найти здесь:

https://drive.google.com/folderview?id=0BwEGIJ1QfjrKY1NNLWRheENyUkE&usp=sharing

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

 
Records - I T I+T
-------------------------------
90000 2.3 3.7 1.5 2.6
170000 2.2 2.3 1.5 3.0
730000 2.2 2.2 1.6 7.6
1450000 2.2 2.3 2.1 11.0
2010000 2.2 2.4 2.0 12.3
2050000 2.2 2.5 2.0 14.3


Почему это происходит? Результаты показывают, что операции и индексы не является проблемой, когда они не используются вместе.

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 3373
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 04.12.15 09:24. Заголовок: А в letodb.ini на се..


А в letodb.ini на сервере случайно нет строки:

Share_Tables = 1

?

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 48
Зарегистрирован: 06.05.14
ссылка на сообщение  Отправлено: 04.12.15 17:02. Заголовок: Да. Но я проверил ва..


Да. Но я проверил вариант Share_Tables = 0 и получил аналогичные результаты:

Records    -    Ind  Tran Ind+T 
-------------------------------
2090000 2.3 10.2 1.5 14.5
2130000 2.1 2.4 1.8 14.6
2170000 2.2 2.3 1.8 14.4
2210000 2.5 2.4 1.9 15.3
2250000 2.3 2.2 2.0 14.8
2290000 2.5 2.7 2.1 15.8
2330000 2.4 2.5 2.0 14.9


Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 3374
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 07.12.15 16:13. Заголовок: Что-то у меня не пол..


Что-то у меня не получается такой результат. А в prg по ссылке нет вообще операций с транзакциями.
Я сделал свой тест с индексом:


PROC Main
Local cPath, nSec, i, nn := 0
Local lTr := .t.

request leto, DBFCDX
RddSetDefault ("LETO")
cPath := "//127.0.0.1:2812/"
Leto_Connect (cPath)

USE (cPath + "wopl") SHARED NEW
SET INDEX TO (cPath + "wopl")

use wop new via "DBFCDX"
go top
nSec := Seconds()
if lTr
wopl->(leto_BeginTransaction(32768))
endif
while ! eof()
wopl->(dbAppend())
for i := 1 to fcount()
wopl->(FieldPut(i, wop->(FieldGet(i))))
next
if nn % 10000 == 0 .and. lTr
wopl->(leto_CommitTransaction())
wopl->(leto_BeginTransaction(32768))
endif
if ++nn == 100000
exit
endif
skip
enddo
if lTr
wopl->(leto_CommitTransaction())
endif
? Seconds() - nSec
// 23.87 -T+I
// 7.32 +T+I

RETURN

Результат работы для 100000 записей:
23.87 сек без транзакций
7.32 сек с транзакциями
Т.е. передача файла, если использовать транзакции, выполняется примерно в 3 раза быстрее.
Одну большую транзакцию я разбил на небольшие по 10000 записей.
Может быть, выложите свой тест, в котором получается медленный результат при использовании транзакций ?

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 49
Зарегистрирован: 06.05.14
ссылка на сообщение  Отправлено: 08.12.15 04:21. Заголовок: DBF Wop (локальный) ..


DBF Wop (локальный) не должен быть больше, чем 10.000 записей. Основная проблема находится в WopL (на сервере). DBF на сервере должен иметь более 500.000 записей и минимум два индекса. Когда есть меньше записей или индекс, скорость увеличивается.

Я пробовал ваш тест программ (Wop = 10k записей):

WopL     Index        -T+I        +T+I 
--------------------------------------
10k 1 4.2 3.9
10k 2 4.2 4.5
2M 1 4.4 7.4
2M 2 4.3 13.0



Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 3375
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 08.12.15 09:31. Заголовок: Большие dbf можно вз..


Большие dbf можно взять здесь:
http://www.gnivc.ru/html/gnivcsoft/KLADR/Base.7z
Я взял doma.dbf, более 2-х млн.записей, размер более 200MB
Создал много (9) индексов:
имя тэга ключ
code 'CODE'
namec 'SUBSTR(CODE,1,11)+UPPER(NAME)'
nasel 'SUBSTR(CODE,1,11)'
nameg 'SUBSTR(CODE,1,8)+UPPER(NAME)'
namemp 'SUBSTR(CODE,1,5)+UPPER(NAME)'
ocato 'OCATD'
gni 'GNINMB'
scode 'SUBSTR(CODE,1,2)'
s_code 'SUBSTR(CODE,1,15)'

Прогнал по сети тест с копированием 100000 записей на сервер letodb без транзакций, и с транзакциями по 10000 записей
Результат теста:
Без транзакций: 154 сек
С транзакциями: 44 сек

Вот чуть измененный тест:

PROC Main
Local cPath, nSec, i, nn := 0
Local cNm := 'doma'
Local lTr := .t.

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
SET INDEX TO (cPath + cNm)

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 == 100000
exit
endif
skip
enddo
if lTr
db_srv->(leto_CommitTransaction())
endif
? lTr, Seconds() - nSec

RETURN


Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 50
Зарегистрирован: 06.05.14
ссылка на сообщение  Отправлено: 08.12.15 19:26. Заголовок: Я использую NTX инде..


Я использую NTX индексы, предполагают, что это может быть проблема. Программа с CDX индексов работать быстрее - время сокращается с 13 до 4,4 секунд. Вы можете проверить это?

К сожалению, я должен использовать NTX индексов.

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 3376
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 09.12.15 09:29. Заголовок: Ну никак не получает..


Ну никак не получается у меня эффект медленной транзакции.
Для ntx копирование 15000 записей с 9 индексами: без транзакции примерно 7 сек, с транзакциями - 6 сек.

letodb.ini:

DataPath = e:/db
EnableFileFunc = 1
EnableAnyExt = 1
Optimize = 1
AutOrder = 1
Default_Driver = NTX

тест:

PROC Main
Local cPath, nSec, i, nn := 0
Local cNm := 'doma'
Local lTr := .t.
Field Code, OCATD, GNINMB

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+'.ntx')
? 'Indexing...'
index on CODE to doma1
index on SUBSTR(CODE,1,11) to doma2
index on SUBSTR(CODE,1,11) to doma3
index on SUBSTR(CODE,1,8) to doma4
index on SUBSTR(CODE,1,5) to doma5
index on OCATD to doma6
index on GNINMB to doma7
index on SUBSTR(CODE,1,2) to doma8
index on SUBSTR(CODE,1,15) to doma9
endif

SET INDEX TO (cPath + cNm + '1')
SET INDEX TO (cPath + cNm + '2')
SET INDEX TO (cPath + cNm + '3')
SET INDEX TO (cPath + cNm + '4')
SET INDEX TO (cPath + cNm + '5')
SET INDEX TO (cPath + cNm + '6')
SET INDEX TO (cPath + cNm + '7')
SET INDEX TO (cPath + cNm + '8')
SET INDEX TO (cPath + cNm + '9')
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


Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 51
Зарегистрирован: 06.05.14
ссылка на сообщение  Отправлено: 09.12.15 18:06. Заголовок: LetoDB.ini: Default_..


LetoDB.ini:
Default_Driver = NTX
EnableFileFunc = 1
Optimize = 1

сервер: Windows Server 2003, 100Mb LAN
рабочая станция: Windows 7


 цитата:
SET INDEX TO (cPath + cNm + '1')
SET INDEX TO (cPath + cNm + '2')
SET INDEX TO (cPath + cNm + '3')
SET INDEX TO (cPath + cNm + '4')
SET INDEX TO (cPath + cNm + '5')
SET INDEX TO (cPath + cNm + '6')
SET INDEX TO (cPath + cNm + '7')
SET INDEX TO (cPath + cNm + '8')
SET INDEX TO (cPath + cNm + '9')
dbSetOrder(1)



Я думаю, что это только открывает последний индекс. Попробуйте:

SET INDEX TO (cPath + cNm + '1'), (cPath + cNm + '2'), (cPath + cNm + '3'), ...

Я попробую тест на другом сервере. Спасибо за помощь!

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 3377
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 09.12.15 18:47. Заголовок: Да, я почти сразу за..


Да, я почти сразу заметил, что пропустил ADDITIVE. Но и с этой опцией результат не изменился.
Попробуйте мой тест с файлом по ссылке, что я дал. Может быть, в вашем тесте есть еще какие-нибудь особенности.

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 52
Зарегистрирован: 06.05.14
ссылка на сообщение  Отправлено: 12.12.15 19:57. Заголовок: результаты: без тра..


результаты:

без транзакций : 8.5
С транзакциями: 6.5

Это нормальный результат. Тогда я изменил DBF, добавил числовое поле ID (N10), заполнил ID = RecNo().
После этого изменил тестовую программу таким образом, чтобы она использует только два индекса:

index on ID to doma1
index on Upper(NAME) to doma2

Потом я получил следующие результаты:

без транзакции: 6.3
С транзакциями: 9.0

Когда я добавил третий числовой индекс:

index on ID to doma3

получил:

без транзакции: 6.4
С транзакциями: 11.2

Кажется, что проблема в числовых полях в индексе.


Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 44 , стр: 1 2 3 All [только новые]
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 686
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет