C#如何在多个用户从远程源引用同一对象时锁定对象

问题描述

我有以下情况:

在我们自己的基础结构上有一个 <LeafletMap center={[this.state.mapLat,this.state.mapLng,]} zoom={17} maxZoom={20} attributionControl={true} zoomControl={false} doubleClickZoom={true} scrollWheelZoom={true} dragging={true} animate={true} easeLinearity={0.35} > <TileLayer url='http://{s}.tile.osm.org/{z}/{x}/{y}.png' /> {markers.map(item => <Marker position={[item.lat,item.lng]} className="heyyya" icon={L.divIcon({ className: 'marker',html: ` <div class="map-icon" id=${item.id}> <div class="circle"> <div class="inner-circle">${item.free_count}</div> </div> </div> `,iconSize: [40,40],iconAnchor: [24,24] })} title={item.free_count} key={item.id} id={item.id} onClick={goToPlace}> </Marker> )} </LeafletMap > ,供10个用户使用。

在客户服务器中,有一项服务会(每5分钟推送一次)在我们的服务器上更新每位员工剩余的一些忠诚度积分。

然后,每个用户都可以在我们的应用程序中选择一个员工,以便他们可以将一些产品添加到他的“种类”购物车中。

所以,让我们说雇员 John 来自存储在我们数据库中的500个积分中的最新忠诚度积分服务。

  1. c# desktop application将3个产品添加到员工购物车中,总计400点。
  2. User X,他同时看到500个可用积分,并且添加了4个产品,总计200点。

User Z将数据保存到我们的数据库时,它将更新该员工的本地剩余积分,因此结果将是500-400 = 100。

User X尝试保存时,我们可以向用户返回一条消息,指出剩余点数不够,因为我们在提交数据库之前先进行了验证。

问题出在客户数据库中的值由于某种原因而被更新并且由于我们无法实时获取数据而无法得知时。因此,在User Z保存400点之前,可能在客户数据库中剩余的点是300。

我一直在尝试思考当客户系统中的雇员少于产品总数时,如何确保用户不将产品添加到我们的数据库中。

任何推荐的解决方案,体系结构?唯一的方法是要求客户向我们公开一个API,以便我们可以在用户数据库中进行任何保存之前实时提取数据吗?

解决方法

如前所述,您没有直接与客户联系,也无法提取任何信息。所以:

每当John尝试执行将导致其要点发生变化的操作时,在执行该操作之前,他都会向服务器发送请求以查看其更衣室对象是否被锁定(John与服务器同步)。

  • 如果更衣室对象被锁定,那么他将收到一条消息,指示他无法执行该操作,因为服务器端用户正在为John添加产品
  • 如果更衣室对象是免费的,则John将在服务器端锁定该更衣室对象,这表明John正在更改点。

您可以应用一些想法:

  1. 如果John的动作会增加重点,那么就不需要在服务器端锁定对象,否则您将锁定它。
  2. 如果John的动作会增加分数,那么不必锁定更衣室对象 反之亦然,您也可以应用想法。

顺便说一句,您可以使用DynaLock NuGet包实时动态创建和管理更衣室对象,而不必担心锁定复杂性,当然,您可以为特定域提供特定的上下文。 DynaLock的源代码位于GitHub