C# PostgreSQL中的锁表

C# PostgreSQL中的锁表,c#,.net,multithreading,postgresql,C#,.net,Multithreading,Postgresql,我有一个表“链接”与一些下载链接 我的.NET应用程序读取此表,获取链接,创建web客户端并下载相关文件。 我想创建几个线程来执行此操作,但每个线程都应该读取不同的记录,否则两个线程将尝试下载相同的文件。 你怎么能做到这一点 我尝试过这个,但不起作用: public static Boolean Get_NextProcessingVideo(ref Int32 idVideo, ref String youtubeId, ref String title) {

我有一个表“链接”与一些下载链接

我的.NET应用程序读取此表,获取链接,创建web客户端并下载相关文件。 我想创建几个线程来执行此操作,但每个线程都应该读取不同的记录,否则两个线程将尝试下载相同的文件。 你怎么能做到这一点

我尝试过这个,但不起作用:

    public static Boolean Get_NextProcessingVideo(ref Int32 idVideo, ref String youtubeId, ref String title)
    {
        Boolean result = false;

        using (NpgsqlConnection conn = new NpgsqlConnection(ConfigurationDB.GetInstance().ConnectionString))
        {
            conn.Open();
            NpgsqlTransaction transaction = conn.BeginTransaction();

            String query = "BEGIN WORK; LOCK TABLE links IN ACCESS EXCLUSIVE MODE; SELECT v.idlink,  v.title " +
                " FROM video v  WHERE v.schedulingflag IS FALSE AND v.errorflag IS FALSE ORDER BY v.idvideo  LIMIT 1; " + 
                " COMMIT WORK;";
            NpgsqlCommand cmd = new NpgsqlCommand(query, conn, transaction);

            NpgsqlDataReader dr = cmd.ExecuteReader();

            if (dr.HasRows)
            {
                dr.Read();


                idVideo = Convert.ToInt32(dr["idvideo"]);
                title = dr["title"].ToString();

                Validate_Scheduling(idVideo); // 
                result = true;
            }

            transaction.Commit();
            conn.Close();

        }
        return result;
    }

你有几个选择。正如您所注意到的,您不想做的一件事是锁定表

  • 顾问锁。优点是这些都是额外的事务性的。缺点是它们在事务中没有关闭,必须专门关闭,并且泄漏最终可能导致问题(本质上是后端的共享内存泄漏)。一般来说,我不喜欢这样额外的事务锁,虽然在db会话结束时会清除建议锁,但陈旧锁仍然可能存在问题

  • 您可以让一个专用线程先提取挂起的文件,然后将特定的检索委托给子线程。就db往返和操作简单性而言,这可能是最好的方法。我希望这是所有解决方案中表现最好的

  • 您可以在可以处理异常处理的存储过程中选择UPDATE NOWAIT。有关示例,请参见


  • 你有几个选择。正如您所注意到的,您不想做的一件事是锁定表

  • 顾问锁。优点是这些都是额外的事务性的。缺点是它们在事务中没有关闭,必须专门关闭,并且泄漏最终可能导致问题(本质上是后端的共享内存泄漏)。一般来说,我不喜欢这样额外的事务锁,虽然在db会话结束时会清除建议锁,但陈旧锁仍然可能存在问题

  • 您可以让一个专用线程先提取挂起的文件,然后将特定的检索委托给子线程。就db往返和操作简单性而言,这可能是最好的方法。我希望这是所有解决方案中表现最好的

  • 您可以在可以处理异常处理的存储过程中选择UPDATE NOWAIT。有关示例,请参见


  • 请看一看建议锁:某种程度上是一种替代方法:如果将挂起的记录集读入主线程,然后将ID传递给新的工作线程,该怎么办?每个线程只负责从数据库中获取细节,完成工作,然后记录结果。通过这种方式,您将消除任何重叠的机会,我猜性能将是相同的,因为在线程中完成的工作将是缓慢的部分。请看一下建议锁:某种替代方法:如果您将挂起的记录集读入主线程,然后将ID传递给新的工作线程?每个线程只负责从数据库中获取细节,完成工作,然后记录结果。通过这种方式,您将消除任何重叠的机会,我猜性能将是相同的,因为线程中完成的工作将是缓慢的部分。