Как выбрать и обновить транзакционно с помощью Linq-To-SQL? - PullRequest
2 голосов
/ 09 августа 2011

Мне нужно выбрать набор записей, которые содержат поле IsLocked.Затем мне нужно немедленно обновить значение IsLocked с false на true в транзакции, чтобы другие программы не извлекали эти уже извлеченные записи для обработки, но могли извлекать другие незаблокированные записи.

Вот кодУ меня так далеко.Это правильно?И как мне сделать обновление?Посетите каждую запись в foreach, обновите значение и затем SubmitChanges ()?Кажется, что когда я запускаю приведенный ниже код, я теряю коллекцию, связанную с emails, поэтому не могу выполнить обработку, которая мне нужна.Приводит ли раннее закрытие транзакции к потере загруженных записей?

Чтобы сфокусировать вопрос: как одна запись загрузки и обновления в транзакции закрывает транзакцию, чтобы не блокировать ее дольше, чем это необходимообработайте записи и сохраните последующие изменения в базе данных.

using (ForcuraDaemonDataContext ctx = new ForcuraDaemonDataContext(props.EmailLogConnectionString))
{
    System.Data.Common.DbTransaction trans = null;
    IQueryable<Email> emails = null;
    try
    {
        // get unlocked & unsent emails, then immediately lock the set for processing
        ctx.Connection.Open();
        trans = ctx.Connection.BeginTransaction(IsolationLevel.ReadCommitted);
        ctx.Transaction = trans;

        emails = ctx.Emails.Where(e => !(e.IsLocked || e.IsSent));
        /// ???
        ctx.SubmitChanges();

        trans.Commit();
    }
    catch (Exception ex)
    {
        if (trans != null)
            trans.Rollback();

        eventLog.WriteEntry("Error. Could not lock and load emails.", EventLogEntryType.Information);
    }
    finally
    {
        if (ctx.Connection.State == ConnectionState.Open)
            ctx.Connection.Close();
    }


    // more stuff on the emails here

}

1 Ответ

0 голосов
/ 14 августа 2011

Пожалуйста, см. этот вопрос для ответа на подобную, более простую форму проблемы.

...