使用多线程时在数据库中插入行?

发布于 2024-11-01 08:56:22 字数 1080 浏览 1 评论 0原文

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

在这里,我上传我的代码片段:

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();
    }
}

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

错误:一个带有以下内容的项目已添加相同的密钥。

提前致谢...:)

Here I am using multi threading and linq to sql.

Here I upload my code snippet:

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);
    }
}

Message Repository class

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();
    }
}

When I run it without threads then it's work fine after include thread I was got following error msg:

Error: An item with the same key has already been added.

Thanks in advance...:)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

孤凫 2024-11-08 08:56:22

您不能以并发方式使用 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 并处置上下文,以便将数据库连接放回池中。

You cannot use a LINQ DataContext in concurrent fashion:

Any instance members are not
guaranteed to be thread safe.

Therefore you need to either serialize access (lock) which will be horribly inefficient, or better use a separate context in each thread:

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);
        }
    }
}

I also hope, for your own sake, that your test has actual logic to wait for the test threads to complete before shutting down... And, of course, properly implement IDisposable in your repository and dispose the context so that the DB connection get placed back in the pool.

极致的悲 2024-11-08 08:56:22

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

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

Uniqueidentifier 的优点是您可以预先选择它,而不用等着看数据库给您什么。

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

I suspect you are using the time as the primary key or as a unique constraint. If so, that's your problem, you should use either an identity or a uniqueidentifier.

Identity will be more readable, since it will be ascending numeric values. It will also be useful since it will generally tell you in what order the records were inserted, which may be useful later on.

Uniqueidentifier has the advantage that you can choose it beforehand instead of waiting to see what the database gives you.

For a logging type application I would recommend an identity column.

美男兮 2024-11-08 08:56:22

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

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

I've had problems in the past with LINQ to SQL DataContexts remembering objects I had previously submitted, and attempting to insert them again the next time I submit. It sounds like you might be running into something similar.

The solution I came up with was to dispose the old DataContext and start over with a new one after each call to SubmitChanges().

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文