使用多线程时在数据库中插入行?
这里我使用多线程和 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您不能以并发方式使用 LINQ DataContext :
因此,您需要序列化访问(锁定),这将非常低效,或者更好地在每个线程中使用单独的上下文:
我也希望,为了您自己的缘故,您的测试具有实际的逻辑来等待测试线程完成之前关闭...当然,在存储库中正确实现 IDisposable 并处置上下文,以便将数据库连接放回池中。
You cannot use a LINQ DataContext in concurrent fashion:
Therefore you need to either serialize access (lock) which will be horribly inefficient, or better use a separate context in each thread:
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.
我怀疑您正在使用时间作为主键或唯一约束。如果是这样,那就是您的问题,您应该使用
identity
或uniqueidentifier
。身份将更具可读性,因为它将是升序的数值。它也很有用,因为它通常会告诉您记录的插入顺序,这在以后可能会有用。
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 auniqueidentifier
.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.
过去,我在使用 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().