开发者

How to select and update transactionally using Linq-To-SQL?

I have a need to select a set of records which contain an IsLocked field. I then need to immediately update the IsLocked value from false to true, within a transaction, such that other programs do not fetch those already-fetched records for processing, but can fetch other, unlocked records.

Here's the code I have so far. Is this correct? And how do I do the update? Visit each record in a foreach, update the value and then SubmitChanges()? It seems that when I run the code below, I lose the collection associated with emails, thus cannot do the processing I need to do. Does closing the transaction early result in losing the records loaded?

To focus the question: how does one load-and-update-in-a-transaction records, close the transaction to not lock for any longer than necessary, process the records, then save subsequent changes back to the database.

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

}


Please see this question for an answer to a similar, simpler form of the problem.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜