代码之家  ›  专栏  ›  技术社区  ›  Waleed Eissa

您的web应用程序中是否使用了锁?

  •  1
  • Waleed Eissa  · 技术社区  · 15 年前

    发布此问题后:

    How to lock on an integer in C#?

    很多答案让我觉得我是一个在我的网络应用程序中使用锁的“罪人”。我从没想过这是个问题(如果用得明智的话),你呢?你在网络应用程序中使用过它吗?

    我不明白如何在不锁定的情况下编写web应用程序,例如,如果您希望从数据库加载一些数据,并且希望确保没有其他线程加载它(也适用于单线程),通常您使用锁定,例如:

    private _locker =  new object();
    private YourClass[] _data;
    public YourClass[] Data
    {
        get
        {
            if(_data == null)
            {
                lock( _locker)
                {
                    // get your data
                   _data = GetYourData();
                }
            }
            return _data;
        }
    }
    

    这个有问题吗?!

    编辑:

    请注意,我这里指的是一个单一服务器场景,对于服务器场,您需要一些分布式锁定机制,但您不希望创建的每个站点在几周内都会获得数百万次的点击,是吗?如果你需要锁定,如果你用分布式锁定创建你的站点,对于一个你不知道是否需要缩放的应用程序来说,这不是太多了吗?除了计算机现在变得非常快之外,一台服务器可以处理大量的流量,这已经被证明了很多次,一些例子是plentyoffish.com和这个你正在使用的网站,做一些谷歌搜索,我相信你会遇到很多其他的。

    6 回复  |  直到 7 年前
        1
  •  11
  •   Jon Skeet    15 年前

    如果使用锁来控制对 遥远的 资源(例如数据库中的某些内容),那么当您尝试扩展到更多服务器时,就会遇到问题。

    如果你只是想 AppDomain -特定的锁(例如,对于缓存)那么它就完全有意义了。

    不过,我不同意你所隐含的断言,即web应用程序不能在没有锁定(在web服务器级别)的情况下编写。它实际上取决于应用程序—通常数据库争用是在数据库而不是web服务器上处理的,这样您的web层中就可以有多台机器。

    对于单子来说这有一定的意义,但是我很少使用单子。。。

        2
  •  3
  •   Chad Grant    15 年前

    是的,您需要再次检查数据。被称为双重检查锁。 http://en.wikipedia.org/wiki/Double_checked_locking_pattern

    理论上,在创建锁之前,第二个线程可以通过第一个空检查。

        if(_data == null)
        {
            lock( _locker)
            {
                if (_data == null) {
                  // get your data
                  _data = GetYourData();
               }
            }
        }
    

    除非你真的真的知道自己在做什么,否则在网络应用程序中这么做是个坏主意。

    我会调查可升级的锁 http://msdn.microsoft.com/en- us/library/system.threading.readerwriterlockslim.enterupgradeablereadlock.aspx

        3
  •  2
  •   Davy Landman    15 年前

    我不知道你是如何访问数据的,但我从来没有发现只需要为一个请求锁定数据库。我不确定,但我可以想象你会尝试用Microsoft Access数据库解决某些问题,但那只是因为它不是一个好的数据库系统,不能用于网站(或任何离开本地桌面的东西)。

        4
  •  1
  •   Steve Willcock    15 年前

    在请求中的某个点锁定本地有争议的资源是可以的(尽管很少)。锁定一个请求并试图在多个请求之间保持锁定实际上不会起到很好的作用。即使你可以让它在一个单一的服务器环境中工作,如果你不得不扩展到一个多服务器环境,那么它也不会像你期望的那样工作。

        5
  •  0
  •   bayer    15 年前

    您尝试访问的远程资源应该负责锁定。正如已经有人指出的,锁是全过程的,一旦你扩大你的锁将无法工作。

    数据库还应该完成所需的所有锁定。这是DBMS的主要要求之一:数据完整性。

        6
  •  0
  •   Rob    15 年前

    我从来不需要在我的任何webapp上使用任何同步机制。除非您处理的是一个多个会话正在更改的原始XML文件,否则我看不到它的必要性。就像这里的大多数人说的-你的数据库会帮你处理的。更新,查询,你有什么,数据库系统(至少是那些你可能与ASP.NET一起使用的)为你负责同步。