如何解决线程冲突因为SQL语句的长时间成本?

时间:2015-07-16 09:14:11

标签: c# sql multithreading sql-server-2008

我要将DataBase O中的一些数据插入到DataBase A中,然后将日志写入DataBase B.现在,我有一个这样的函数:

list=DataBaseO.getdata();
if(list.id not in DataBaseB)
{
    insert data into DatabaseA;
    insert log into DatabaseB;
}

它只是按我的意愿运行。但是当我把它放入多线程程序时,它却出错了。日志很大,因此将它插入DataBase B需要花费大量时间。当线程1尝试插入日志时,线程No.2已经尝试查找list.id是否在BataBase B中。所以,我最终在DatabaseA中获得了2个相同的数据。我能解决这个问题吗?

Ps,我正在使用C#

2 个答案:

答案 0 :(得分:1)

您可以使用Lock锁定操作。这样你就可以让线程在彼此等待。使用您的示例代码,它看起来像:

list=DataBaseO.getdata();
if(list.id not in DataBaseB)
{
lock(theLock) {
        insert data into DatabaseA;
}
lock (theLock) {
        insert log into DatabaseB;
}
}

你必须申报“锁定”。在你开始你的线程并让它可访问之前的某个地方。锁对象可以是任何类型的Object,我个人倾向于只使用一个基本的Object。

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

答案 1 :(得分:0)

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

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

所以你的代码看起来像这样:

list=DataBaseO.getdata();
if(list.id not in DataBaseB && logsInsertedFlag )
{
    logsInsertedFlag = false;
    insert data into DatabaseA;
    insert log into DatabaseB;
    logsInsertedFlag = true;
}

无论如何,正如我个人认为的那样,加快流程速度的唯一方法就是加快将日志纳入DatabaseB。

希望我的回答有所帮助。