代码之家  ›  专栏  ›  技术社区  ›  Mike Florian Doyen

WebServices作为单例是否会导致不同用户出现问题?

  •  4
  • Mike Florian Doyen  · 技术社区  · 14 年前

    我正在开发一个使用UPS Shipping Web服务的电子商务应用程序。我已经读到创建一个单例很好,所以在任何时候只有一个WebService实例。我的代码如下。

    Public Class Ship
        Private Shared sync As New Object()
        Private Shared _Service As New ShipService
    
        Public Shared ReadOnly Property Service As ShipService
            Get
                If _Service Is Nothing Then
                    SyncLock sync
                        If _Service Is Nothing Then
                            _Service = New ShipService
                        End If
                    End SyncLock
                End If
                Return _Service
            End Get
        End Property
    
        Public Shared Function GetInstance() As ShipService
            Return Service()
        End Function
    End Class
    

    这是一个片段,它将在哪里使用。

    Public Sub New(ByVal ToAddress As Address, ByVal WeightInLbs As String)
        //Not relevant code
        Ship.Service.UPSSecurityValue = Security
        //More not relevant code 
    End Sub
    
    Public Function ProcessShipment() As ShipmentResponse
        Return Ship.Service.ProcessShipment(ShipmentRequest)
    End Function
    

    在上面的构造函数行中,我必须设置服务的upSecurityValue。稍后我将调用processShipment函数。我的问题是:既然WebService被看作是一个单实例,那么不同的应用程序实例可以共享相同的upSecurityValue,并且在我设置它和调用processShipment之间会发生变化吗?

    1 回复  |  直到 7 年前
        1
  •  1
  •   SqlRyan    14 年前

    在您所做的事情中,它可能会在您调用new和设置安全值之间以及您实际处理发货之间发生明显的变化。应用程序的所有用户(在同一个Web应用程序中,也就是说,如果您的服务器上有此应用程序的多个副本,那么每个用户都会使用自己的singleton)共享singleton,因此所有用户都将共享相同的数据。

    如果多个用户同时运行应用程序(或用户2仅落后1毫秒):

    User1                           User2
    New (sets security code)
                                    New (sets security code)
    ProcessShipment
                                    ProcessShipment 
    

    两个发货都将使用用户2的安全代码进行处理,这不是您想要的。安全地做到这一点的方法可能是在您发送包时将安全性传递到函数中,然后立即使用它-如果您将其存储以供以后使用,甚至是在以后使用一条指令,那么您就将自己设置为一个争用条件,用户可以在该条件下读取彼此的数据。