【问题标题】:Keeping multi-user state across DB sessions跨数据库会话保持多用户状态
【发布时间】:2020-09-28 10:40:13
【问题描述】:

情况

假设我们有一个连接到 (Postgre)SQL 数据库的 Web 应用程序,其任务可以概括为:

  1. 用于可视化数据的SELECT 操作。
  2. UPDATE 操作,根据可视化数据存储修改。

简单,但是...所涉及的数据不是特定于用户的,因此可能会在此过程中被其他用户更改。编辑任务可能需要很长时间(可能超过一个小时),这意味着发生这些冲突的概率并不低:对问题实施稳健的解决方案是有意义的。

方法

这个想法是,一旦用户尝试提交更改(即触发UPDATE 操作),将触发一些数据库检查以确保所涉及的数据在此期间没有更改。

假设我们对数据的每一次更改都设置了时间戳,这就像保持数据为SELECTed 时的访问时间并确保在此时间之后对所涉及的数据没有进行任何新更改一样简单。

问题

我们可以很容易地在用户执行编辑时将访问时间保留在前端应用程序中,然后在执行UPDATE 时将其作为触发器函数的参数提供,但出于安全原因,这是不可取的。数据库应该存储用户的访问时间。

一个直观的解决方案可能是与数据库会话关联的TEMPORARY TABLE。但是,同样,用户可能需要很长时间才能完成任务,因此从池中捕获连接并使其长时间保持空闲似乎也不是一个好的选择。 SELECTUPDATE 操作将在不同的会话下执行。

问题

是否有任何范式或规范的方法可以有效地解决和解决这个问题?

【问题讨论】:

  • "因此从池中捕获连接并使其长时间处于空闲状态似乎也不是一个好的选择"您希望一次进行多少这样的会话?
  • “但出于安全原因,这是不可取的” 你能描述一下安全原因吗?

标签: sql database postgresql web-applications data-modeling


【解决方案1】:

这个问题被称为“丢失更新”问题。

有几种解决方案取决于是否使用连接池以及使用的transaction isolation level

  1. 悲观锁定 SELECT ... FOR UPDATE 没有连接池
  2. 如果使用连接池,则使用时间戳列进行乐观锁定。

【讨论】:

  • 感谢您的回答!其实我之所以不认为这是一个经典的“丢失更新问题”,是因为读写阶段,严格来说,并不是封装在同一个事务中,而是封装在两个不同的事务中(甚至是两个不同的会话)。您提出的第二种方法似乎是我所询问的,我会研究一下。
猜你喜欢
  • 2012-08-10
  • 2013-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多