【问题标题】:Insert row in DB while using multithreads?使用多线程时在数据库中插入行?
【发布时间】:2011-04-15 13:01:44
【问题描述】:

这里我使用多线程和 linq to sql。

这里我上传我的代码sn-p:

public class PostService
{ 
    MessageRepository objFbPostRespository = new MessageRepository();
    public void callthreads()
    {
        for (int i = 0; i < 100; i++)
        {
            Thread th = new Thread(postingProcess);
            th.Start();
        }
    }

    public void postingProcess()
    {
        objFbPostRespository.AddLog("Test Multithread", DateTime.Now);
    }
}

消息库类

class MessageRepository
{        
    DataClassesDataContext db_Context = new DataClassesDataContext();
    public void AddLog(string Message, DateTime CurrentDateTime)
    {
        FbMessgaeLog FbMessage = new FbMessgaeLog
        {
            Message = Message,
            Time = CurrentDateTime                
        };
        db_Context.FbMessgaeLogs.InsertOnSubmit(FbMessage);
        db_Context.SubmitChanges();
    }
}

当我在没有线程的情况下运行它时,在包含线程后它工作正常我收到以下错误消息:

错误:已添加具有相同键的项目。

提前谢谢...:)

【问题讨论】:

  • 你的数据库在这里使用什么作为它的键?
  • @Jens 我假设它是一个数据库标识列,这是主要问题
  • 您选择多线程方法的要求是什么?你不能使用队列来推送项目以立即写入和返回,并让后台工作人员按顺序完成工作吗?

标签: sql-server multithreading linq c#-4.0


【解决方案1】:

您不能以并发方式使用 LINQ DataContext

任何实例成员都不是 保证是线程安全的。

因此,您需要序列化访问(锁定),这将非常低效,或者更好地在每个线程中使用单独的上下文:

public class PostService
{ 
    public void callthreads()
    {
        for (int i = 0; i < 100; i++)
        {
            Thread th = new Thread(postingProcess);
            th.Start();
        }
    }

    public void postingProcess()
    {
        using (MessageRepository objFbPostRespository = new MessageRepository())
        {
           objFbPostRespository.AddLog("Test Multithread", DateTime.Now);
        }
    }
}

我也希望,为了您自己,您的测试有实际的逻辑来等待测试线程在关闭之前完成......当然,在您的存储库中正确实现 IDisposable 并处理上下文,以便数据库连接被放回池中。

【讨论】:

    【解决方案2】:

    我怀疑您将时间用作主键或唯一约束。如果是这样,那是您的问题,您应该使用identityuniqueidentifier

    身份将更具可读性,因为它将是升序数值。它也很有用,因为它通常会告诉您记录的插入顺序,这在以后可能会很有用。

    Uniqueidentifier 的优点是您可以预先选择它,而不是等待查看数据库为您提供什么。

    对于日志记录类型的应用程序,我建议使用标识列。

    【讨论】:

      【解决方案3】:

      过去,我在使用 LINQ to SQL DataContexts 记住我之前提交的对象时遇到问题,并在下次提交时尝试再次插入它们。听起来您可能会遇到类似的情况。

      我想出的解决方案是处理旧的 DataContext 并在每次调用 SubmitChanges() 后重新开始。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-02
        • 2019-07-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多