【问题标题】:Is there a proper way of ensuring only one user at a time makes changes to an object with REST+HTTP?是否有一种正确的方法可以确保一次只有一个用户使用 REST+HTTP 对对象进行更改?
【发布时间】:2012-02-06 10:13:12
【问题描述】:

我创建了一个 Django/Tastypie 应用程序,其中多个人可能会同时更改数据库中一行的属性,或者可能 PUT 过时的数据。

例如:

 # the Django model
 class Thing(models.Model):
      name = models.CharField(max_length=100)
      description = models.TextField()

 # the Tastypie Resource
 class ThingResource(ModelResource):
       class Meta:
           queryset = Thing.objects.all()

现在假设任意数量的用户可以随时更改Thingnamedescription。他们可以同时进行,或者有人可以让应用程序打开很长时间,然后再回来更改它。

我要避免的是不正确的潜在更改。鉴于以下情况:

#1 User 1: Opens app viewing Thing #1 with name = "my name", description = "my description"
#2 User 2: Opens app viewing Thing #1 (same state as User 1)
#3 User 2: Changes description of Thing #1 to "something"
#4 User 1: Changes name of Thing #1 to "some other name"

#4 行之后,事物#1 的状态应该是name = "some other name", description = "something" 而不是name = "some other name", description = "my description"

假设应用程序不提前知道(实时或通过定期更新页面上的数据)服务器上的对象已更改,如何防止这种情况发生?

我考虑添加一个字段sequence = models.PositiveIntegerField(),每次更新时我都会在其中增加它,这样我就可以在更新发生时判断对象是否已过期,但这是最好的方法吗?有没有更好的办法?这似乎是一种常见的模式,对吧?

【问题讨论】:

  • 保留版本号是一种被广泛接受的良好做法。您当然应该在后端使用某种事务性数据库,否则任何此类方案都无法确保正确的行为。
  • 是的,我正在使用 PostgreSQL。感谢您指出这一点

标签: javascript django http rest tastypie


【解决方案1】:

使用 REST,资源的状态由服务器管理,因此您对序列字段的想法是正确的。服务器跟踪资源所在的版本,客户端在发送新版本时说明它认为正在创建的版本。如果客户端弄错了,服务器会告诉它。

Ian’s suggestion of ETags or modified dates 听起来是正确的做法,this answer to a similar question 表示同意。我自己实际上并没有太多这方面的经验。

【讨论】:

  • 我赞成确认我的方法有效。感谢您链接其他答案,非常有用。
  • @diamotte:不客气,我认为关于 ETags 可能只是版本号(而不是内容的哈希)的一点非常有趣。
【解决方案2】:

RESTful 方法是让客户端跟踪与资源一起返回的 Last-Modified 标头或 Etag 标头。然后,当它发布时,添加一个标题,如

If-Unmodified-Since: <date-noted-from-initial-GET>

If-Match: <etag-noted-from-initial-GET>

如果自客户端最初下载资源后服务器上的资源已被修改,则服务器应返回“Precondition Failed”响应。然后客户端可以检索当前版本并显示对用户有意义的内容。

不过,让 sweetpie 响应这些标头可能有点困难。

【讨论】:

  • 非常有趣。我很久以前就读过 Etags,但现在我明白了它们应该如何工作。你是对的,要让美味派正确回应这些问题需要做很多工作,我不确定我是否能做到这一点。感谢您的回答。
猜你喜欢
  • 2013-05-04
  • 1970-01-01
  • 1970-01-01
  • 2014-10-20
  • 2015-11-02
  • 2021-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多