【问题标题】:Get sequence number thread safely安全获取序列号线程
【发布时间】:2015-08-13 23:47:05
【问题描述】:

我有一个 ASP.NET 应用程序,在使用实体框架在表中创建记录时,我使用数据库序列中的序列号。我有一个存储过程,它检索从实体框架调用的序列中的下一个值,我想确保这个检索是线程安全的。

我使用this 回答在以下课程中尝试这样做:

public static class SequenceNumber
{
    private static object Lock = new object();

    public static long Next(Context db)
    {
        long next = 0;

        lock (Lock)
        {
            next = db.GetNextComplaintNumber().Single().Value;
        }

        return next;
    }
}

这会确保线程安全吗?

【问题讨论】:

  • 为了什么?对于GetNextComplaintNumber 的范围是的,但是任何调用Next 的线程都会与其他线程混淆。如果你想确保GetNextComplaintNumber同时只被调用一次,你应该依赖数据库事务处理。
  • 一个数据库序列应该总是给出一个唯一的编号,所以调用它应该没有问题,从多个线程调用它应该没有问题,你认为会出错的地方是什么?
  • @Manr101:我需要将所有数字精确地递增 1,并且永远不会跳过一个数字。

标签: c# multithreading thread-safety


【解决方案1】:

Next(...) 方法将是线程安全的,但 db.GetNextComplaintNumber() 不会是线程安全的(除非它被实现为)。锁确保任何调用 Next(...) 的线程都必须等待轮到它们运行锁语句中的任何内容。但是,如果任何其他线程可以访问对象 db,那么它们可以有效地调用 db.GetNextComplaintNumber() 而无需调用 Next(...) 方法,因此它不会受到 lock 语句的保护。如果您可以保证 db.GetNextComplaintNumber() 仅在 Next(...) 方法中被调用,那么您应该是安全的,否则您需要在 db.GetNextComplaintNumber() 方法中实现线程安全。

【讨论】:

  • 好的,这行得通。此类的想法是使其成为访问 EF 上下文中的 GetNextComplaintNumber() 的唯一点。谢谢
猜你喜欢
  • 2019-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-09
  • 1970-01-01
  • 2010-10-11
  • 2013-04-29
  • 1970-01-01
相关资源
最近更新 更多