C # - пакетное выполнение хранимых процедур - PullRequest
1 голос
/ 23 ноября 2011

В настоящее время у меня есть приложение WinForms, написанное на C #.

Все наши обновления выполняются посредством выполнения хранимых процедур.У нас на одном экране ситуация, когда на этом экране вызывается до 60 обновлений.В настоящий момент каждый вызов обновления обрабатывается один за другим, и у некоторых клиентов, которые имеют медленное соединение между клиентом и сервером, возникают проблемы со скоростью.Я вполне уверен, что если я смогу отправить все эти вызовы в базу данных одновременно, это сэкономит много времени ожидания на стороне клиента (в настоящее время для каждого из этих 60 вызовов вызывается ExecuteNonQuery, а клиент ожидаетtrue / false результат перед продолжением, и это вызывает задержку).

Как лучше всего объединить все эти вызовы в один вызов SQL?Мы думали о том, чтобы поместить весь код в транзакцию, но нужно как можно больше избегать блокировок, так как в любой момент времени системой пользуются многие одновременные пользователи.обновить записи на сервере.Мы даже не требуем никакого ответа от хранимых процедур, которые выполняются.По сути, я хочу объединить несколько вызовов кода, приведенного ниже, в один вызов, и мне интересно, как лучше всего это сделать:

        public virtual bool Update(DataRow dataRow, Guid userId)
    {
        SqlCommand cm = null;
        bool ret = true;
        try
        {
            cm = Utilities.GetSqlUpdateCommand(dataRow, userId);
            ExecuteNonQuery(cm);              
        }
        catch (SqlException ex)
        {
            LogDataAccessBaseError(ex);
            ret = false;
            throw;
        }
        finally
        {
            if (cm != null)
            {
                cm.Dispose();
            }
        }

        return ret;
    }

Ответы [ 4 ]

0 голосов
/ 23 ноября 2011

Используете ли вы SQL Server 2008 или более позднюю версию, и все ли вызовы хранимых процедур идентичны (кроме отдельных параметров)?

Если это так, вы можете заняться созданием версии хранимой процедуры, которая принимаетa Табличный параметр ( ADO ).Это позволит вам передавать все строки на сервер SQL в виде одной таблицы.


Если нет, то я предполагаю, что GetSqlUpdateCommand в настоящее время создает SqlCommand с именем хранимой процедурыи добавление соответствующих параметров.Другой подход:

Изменить GetSqlUpdateCommand, чтобы он мог принять существующий объект SqlCommand.Затем он добавляет новый вызов exec StoredProcedure @Parm1,@Parm2,@Parm2 и добавляет эти параметры.Необходимо убедиться, что он использует новые имена для добавляемых параметров, чтобы он не конфликтовал с другими вызовами exec.Вам также может понадобиться настроить эту функцию так, чтобы она могла определять, когда вы приближаетесь к пределу количества параметров, которые вы можете передать, в этот момент она должна выполнить эту команду, а затем создать новую.

Например, он создает текстовую команду, такую ​​как:

exec MegaProcedure @Parm1,@Parm2,@Parm3
exec MegaProcedure @Parm4,@Parm5,@Parm6
exec MegaProcedure @Parm7,@Parm8,@Parm9

Наконец, я думаю, что вы не понимаете, что такое транзакции / делают - они магически не связывают несколько вызовов вместе, поэтому они выполняются с меньшими затратамивремя наверх / туда и обратно.Они являются просто и просто механизмом, с помощью которого можно откатить работу, поэтому здесь они не помогут.

(И, фактически, каждый оператор в SQL в любом случае выполняется внутри транзакции - это просто так,по умолчанию эта транзакция открывается автоматически при запуске оператора и фиксируется при успешном завершении оператора)

0 голосов
/ 23 ноября 2011

Нужно ли делать звонки в каком-то определенном порядке? Многопоточность может помочь, если нет.

Лучший ответ на ваш вопрос зависит от того, насколько вы контролируете каждый конец процесса. В идеале вы просто должны сделать один вызов, который вернет один большой кусок данных, содержащих все, что вам нужно. Помните, что при возврате данных из хранимых процедур хранимая процедура может возвращать несколько операторов выбора, и вы можете перебирать возвращенные наборы записей. Таким образом, один сохраненный процесс потенциально может вернуть все, что вам нужно. Возможно, не имеет смысла оборачивать все в один хранимый процесс в зависимости от того, какие параметры нужны запросу, но вы, вероятно, могли бы обернуть его в несколько вызовов по крайней мере.

0 голосов
/ 23 ноября 2011

Может помочь полусинхронный и полусинхронный шаблон.По сути, вы помещаете весь запрос в очередь, а затем элементы извлекаются клиентами.

См. http://www.cs.wustl.edu/~schmidt/PDF/PLoP-95.pdf для абстрактной концепции.

0 голосов
/ 23 ноября 2011

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

Еще один способ сделать его полностью на стороне клиента, как вы сами указали, использовать транзакции.Поскольку я ничего не знаю о том, что должны делать ваши хранимые процедуры, я не могу сказать, как здесь избежать блокировок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...