F# — FSharp.Data.SqlClient — Как указать время ожидания для обновления

Я использую поставщиков типа FSharp.Data.SqlClient для доступа к базе данных SQL-сервера. Итак, я настроил типы в F# следующим образом:

type ClmDB = SqlProgrammabilityProvider<ClmSqlProviderName, ConfigFile = AppConfigFile>
type ResultDataTable = ClmDB.dbo.Tables.ResultData
type ResultDataTableRow = ResultDataTable.Row

а затем я использую его примерно так:

let saveResultData (r : ResultData) (conn : SqlConnection) =
    let t = new ResultDataTable()
    let newRow = r.addRow t
    t.Update(conn) |> ignore
    newRow.resultDataId

где ResultData — некоторый тип, который «знает», как преобразовать себя в строку ResultDataTable (ResultDataTableRow). Расширение r.addRow t делает это.

Все отлично, за исключением того, что строка, которую я вставляю, может быть довольно большой (размером 25-30 МБ), и поэтому у меня плохое предчувствие, что t.Update(conn) может случайно истечь, особенно из-за почти 100% загрузки процессора (вычислительная система ядро предназначено для потребления всех ресурсов обработки, хотя и с низким приоритетом). Наведение курсора на t.Update не показывает никакого способа указать время ожидания, и любое время ожидания на уровне соединения связано, ну, с соединением, а не с транзакцией вставки ☹.

Итак, вопрос в том, как указать тайм-аут для транзакции Update.

Большое спасибо!

Обновление 20190116. Пока t.Update(conn) выше работает без тайм-аутов на моем компьютере при вставке строк данных размером 95 МБ на 100 % ниже нормальной нагрузки некоторых других вещей, работающих там. Я еще не измерял фактическое время для таких транзакций. Если я это сделаю, я обновлю это.


person Konstantin Konstantinov    schedule 09.01.2019    source источник
comment
Привет, вы пытались добавить тайм-аут в строку подключения? Я смотрю на FSharp.Data.SqlClient, но не вижу параметров.   -  person Sanpas    schedule 09.01.2019
comment
@pascalsanchez Согласно спецификации, время ожидания строки подключения предназначено для открытия соединения, а не для выполнения команды: docs.microsoft.com/en-us/dotnet/api/ :( Но при отсутствии чего-либо еще стоит попробовать.   -  person Konstantin Konstantinov    schedule 09.01.2019
comment
Извините . Да, я пытался прочитать эту документацию сегодня, но я не нашел соответствующей информации. мне нужно время, чтобы посмотреть. По этим вопросам github.com/fsprojects/FSharp.Data.SqlClient/issues/98 они упоминают о выключении CommandTimeout   -  person Sanpas    schedule 09.01.2019
comment
@pascalsanchez Я смотрю на источник: github.com/fsprojects/FSharp.Data.SqlClient/blob/master/src/ и похоже, что время ожидания команды для таблицы Update не установлено :(   -  person Konstantin Konstantinov    schedule 09.01.2019
comment
Я вижу то же самое. У вас не было возможности изменить свой код для использования некоторых других функций, обеспечивающих тайм-аут? Или другим способом было открыть вопросы на github, я думаю, это хороший способ. Прошу прощения за плохую помощь, но сегодня я не работал с F#.   -  person Sanpas    schedule 10.01.2019
comment
@pascalsanchez Спасибо за помощь. Я открыл тикет с разработчиком: github.com/fsprojects/FSharp.Data.SqlClient /issues/324 Посмотрим, ответят ли они.   -  person Konstantin Konstantinov    schedule 10.01.2019


Ответы (1)


Вы не можете указать тайм-аут для метода Update предоставленного DataTable, поскольку текущая реализация поставщика типов не предусматривает такую ​​функцию.

Однако, как указано в документации, у вас может быть несколько вариантов настройка поведения по умолчанию.

Кроме того, поскольку ваш вариант использования напоминает вставку одной строки в таблицу, я бы придерживался реализации с помощью SqlCommandProvider, используя необязательный параметр commandTimeOut его конструктора для установки желаемого значения тайм-аута timespan, как во фрагменте ниже:

type AddRow = SqlCommandProvider<"path to the parameterized INSERT statement", designTimeConnection> 
..............................
(new AddRow(runTimeConnection, commandTimeOut=timespan)).Execute(...arg=value...) |> ignore
person Gene Belitski    schedule 10.01.2019
comment
Ага. Я действительно не хочу идти по этому пути, так как это фактически требует написания операторов SQL на F #. Я не думаю, что это правильный путь. С другой стороны, я не могу указать время ожидания для метода Update, если только я не разветвлю и не сделаю это. Учитывая, что у меня уже есть локальные исправления ошибок для двух проектов F#/C# с ​​открытым исходным кодом, это делает его третьим ☹. А это значит, что у меня будет как минимум три источника, которые мне придется вручную сверять с репозиториями. Это становится отвратительным ☹. Я открыл тикет с разработчиками и посмотрим, получится ли. - person Konstantin Konstantinov; 12.01.2019
comment
@KonstantinKonstantinov: Современный опыт использования этого TP в контексте производства предприятия показывает, что обычный шаблон использования сводится к ADO со статически контролируемой структурой записи и типами полей. Сущности, такие как пользовательские DataTable, больше подходят для непроизводственного использования типа исследовательского программирования и сознательно могут не иметь определенных функций. Например, отсутствие поддержки асинхронности в DataTable методах. - person Gene Belitski; 13.01.2019
comment
Асинхронная поддержка в F# очевидна из-за структуры async {...}, MailboxProcessor и т. д. Так что я не думаю, что нам нужен этот C#-подобный зоопарк синхронных/асинхронных методов в F# ????. Я хочу сказать, что в настоящее время, если мне нужен тайм-аут для метода таблицы Update, то единственный способ получить это (благодаря открытому исходному коду) - это клонировать репо и просто сделать это. С положительной стороны, я думаю, что я (пока) не нажимаю тайм-ауты, вставляя 30-мегабайтные строки двоичных данных. Возможно, стоит перенести такие BLOBы в файловое хранилище, но это уже не вопрос. - person Konstantin Konstantinov; 14.01.2019
comment
Было бы в истинном духе OSS, если бы вы, вместо того, чтобы разветвляться и хранить локально, действительно отправляйте PR для ошибок и функций, которые вы устранили. - person Gene Belitski; 14.01.2019
comment
Я сделал это для обоих местных форков. Поскольку ничего не происходило с открытыми билетами в течение нескольких месяцев, я просто пошел дальше. Вот одна ошибка: github.com/mathnet/mathnet-numerics/issues/595 Его нет уже около 5 месяцев :( - person Konstantin Konstantinov; 14.01.2019
comment
В конце концов я сдался, сгенерировал операторы SQL INSERT/UPDATE (мне нужно было сделать это только для двух тяжелых таблиц данных с менее чем 20 столбцами в каждой), скопировал и вставил в F #, заменил некоторые вещи SQL, добавил тайм-аут соединения и менее 15 минут все это пинается и кричит без изменения звонящих! Еще раз спасибо за советы! - person Konstantin Konstantinov; 25.01.2019