2015-08-13 62 views
1

我有一个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; 
    } 
} 

这是否会确保线程安全?

+0

对于什么?对于'GetNextComplaintNumber'的范围是的,但是任何调用'Next'的线程都会与其他线程混淆。如果你想确保'GetNextComplaintNumber'只被同时调用一次,你应该依赖数据库事务处理。 –

+0

一个数据库序列应该总是给一个唯一的数字,所以调用它,所以从多个线程调用它应该没有问题,你认为会出错的是什么? – Mant101

+0

@ Manr101:我需要所有数字都精确地加1,并且一个数字永远不会被跳过。 – Carel

回答

1

Next(...)方法将是线程安全的,但db.GetNextComplaintNumber()不会(除非它被实现为)。该锁确保任何调用Next(...)的线程都必须等待轮到它运行锁语句中的任何内容。但是,如果任何其他线程都有权访问对象数据库,那么他们可以在不调用Next(...)方法的情况下有效地调用db.GetNextComplaintNumber(),以便它不受锁定语句的保护。如果你可以保证db.GetNextComplaintNumber()只在Next(...)方法中调用,那么你应该是安全的,否则你会想要在db.GetNextComplaintNumber()方法中实现线程安全。

+0

好的,这将起作用。这个类的想法是它是EF上下文中GetNextComplaintNumber()的唯一访问点。谢谢 – Carel