Can Webservices as singletons cause issues with different users?
I am developing an ecommerce app that is using the UPS shipping webservice. I have read that it is good to create a singleton so there is only one instance of a webservice at any time. My code for that is below.
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
Here is a snippet from where it will be used.
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
Ret开发者_Go百科urn Ship.Service.ProcessShipment(ShipmentRequest)
End Function
In the line above in the constructor I have to set the UPSSecurityValue of the service. Then later I will call the ProcessShipment function. My question is; Since the webservice is being traeted as a singleton could different instances of the app share that same UPSSecurityValue and could it change between when I set it and when I call ProcessShipment?
In the case of what you're doing, it could definately change between when you call New and set the Security value and when you actually process the shipment. The singleton is shared across all users of your application (within the same web app, that is - if you had multiple copies of this app on your server, they'd each use their own singleton), so all users will share the same data.
If multiple users run through the application at the same time (or User2 is only 1ms behind):
User1 User2
New (sets security code)
New (sets security code)
ProcessShipment
ProcessShipment
Both shipments will process with User2's security code, which isn't what you want. The way to do this safely could be to pass the security into the function when you ship the package, and then consume it immediately - if you store it for use later, even a single instruction later, you're setting yourself up for a race condition where users read each other's data.
精彩评论