Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何解决由于SQL语句的长时间开销而导致的线程冲突?_C#_Sql_Multithreading_Sql Server 2008 - Fatal编程技术网

C# 如何解决由于SQL语句的长时间开销而导致的线程冲突?

C# 如何解决由于SQL语句的长时间开销而导致的线程冲突?,c#,sql,multithreading,sql-server-2008,C#,Sql,Multithreading,Sql Server 2008,我要将数据库O中的一些数据插入数据库A,然后将日志写入数据库B。现在,我有一个如下函数: list=DataBaseO.getdata(); if(list.id not in DataBaseB) { insert data into DatabaseA; insert log into DatabaseB; } list=DataBaseO.getdata(); if(list.id not in DataBaseB && logsInsertedFlag

我要将数据库O中的一些数据插入数据库A,然后将日志写入数据库B。现在,我有一个如下函数:

list=DataBaseO.getdata();
if(list.id not in DataBaseB)
{
    insert data into DatabaseA;
    insert log into DatabaseB;
}
list=DataBaseO.getdata();
if(list.id not in DataBaseB && logsInsertedFlag )
{
    logsInsertedFlag = false;
    insert data into DatabaseA;
    insert log into DatabaseB;
    logsInsertedFlag = true;
}
但当我把它放到一个多线程程序中时,它却出了问题。日志太大,因此将其插入数据库B需要花费大量时间。当线程1尝试插入日志时,线程2已经在尝试查找list.id是否在BataBase B中。因此,我最终在数据库a中获得了2个相同的数据。我如何解决此问题


另外,我使用的是C#

您可以使用。这样你就可以让线程互相等待。对于您的示例代码,它将如下所示:

list=DataBaseO.getdata();
if(list.id not in DataBaseB)
{
lock(theLock) {
        insert data into DatabaseA;
}
lock (theLock) {
        insert log into DatabaseB;
}
}
在启动线程并使其可访问之前,您必须在某个地方声明'theLock'。锁对象可以是任何类型的对象,我个人倾向于使用基本对象


请注意,如果希望完成整个过程(将数据写入数据库A,将日志写入数据库B),也可以将两个操作锁定在同一个锁中。在这两种情况下,多线程都不会给您带来多大的性能提升,因为线程会不断地相互等待以访问数据库

尝试设置一个标志,指示数据库B中的日志是否已完成插入。因此,如果另一个线程将尝试获取数据,它将等待直到清除该标志。(为线程使用计时器,它将定期检查标志)

不用说,您应该只声明您的标志的一个实例。因此,要么在DB中设置您的标志,要么在代码中声明它static(取决于来自多个应用程序的线程是否会检查此标志,或者只有一个应用程序始终在运行)

因此,您的代码如下所示:

list=DataBaseO.getdata();
if(list.id not in DataBaseB)
{
    insert data into DatabaseA;
    insert log into DatabaseB;
}
list=DataBaseO.getdata();
if(list.id not in DataBaseB && logsInsertedFlag )
{
    logsInsertedFlag = false;
    insert data into DatabaseA;
    insert log into DatabaseB;
    logsInsertedFlag = true;
}
无论如何,在我个人看来,加快进程的唯一方法就是加快将日志插入数据库B的速度


希望我的回答能有所帮助。

lock()在这里不起作用,SQL语句已经发送到服务器,对象已经释放。但是服务器需要时间来处理它。啊,我的错,我想你想等待事务完成。那你怎么做日志插入呢?如果它是一个事务,sql server在完成重建其索引(也称为“处理所有数据”)之前永远不能发出数据。是否通过执行远程作业来完成?在第一个命令完成并提交之前,不要发送第二个命令?