ProstgreSQL、MySQL乐观并发

ProstgreSQL、MySQL乐观并发,sql,mysql,postgresql,concurrency,optimistic-concurrency,Sql,Mysql,Postgresql,Concurrency,Optimistic Concurrency,我有一个web应用程序,其中用户可以同时更改数据。目前,我在每个表单中包含旧的行值,并且仅当数据相同时才更新行。对于SQLite,这将是唯一的选项。这是丑陋的,我认为切换到另一个SQL数据库,如果它能提供一个更好的方法来做到这一点。PostgreSQL或MySQL是否有隐式的行时间戳或版本号,您可以使用它们?MySQL有一个时间戳数据类型,当与默认当前时间戳和更新当前时间戳约束结合使用时 在PostgreSQL中,每个名为xmin的表上都有一个“隐藏字段”,可用于确定行版本。AFAIK,在Pos

我有一个web应用程序,其中用户可以同时更改数据。目前,我在每个表单中包含旧的行值,并且仅当数据相同时才更新行。对于SQLite,这将是唯一的选项。这是丑陋的,我认为切换到另一个SQL数据库,如果它能提供一个更好的方法来做到这一点。PostgreSQL或MySQL是否有隐式的行时间戳或版本号,您可以使用它们?

MySQL有一个
时间戳
数据类型,当与
默认当前时间戳
更新当前时间戳
约束结合使用时


在PostgreSQL中,每个名为
xmin
的表上都有一个“隐藏字段”,可用于确定行版本。

AFAIK,在Postgres中获取更新时间戳需要一个触发器,请参见这个非常类似的问题:


这个问题(以及Eric的回答)指出MySQL支持这种不带触发器的方式。

使用数字计数器比使用时间戳要好。无论时间戳多么精确,都有可能同时提交两个版本的数据并获得相同的时间戳。通过使用数字计数器(例如,
updatemytable set counter=counter+1,data=?where id=?和counter=?
),然后每次更改行时,它都会获得一个唯一的计数器值。(在where子句中提供原始计数器值,如果其他人更改了数据,则不会匹配任何行。)


虽然这不是一个“隐含”的解决方案,但我认为它是可以的。Hibernate之类的库有一些工具可以让您自动完成这类工作,因此,您的代码不必担心。

是当事务正在进行并更新了行时,
xid
才更新,还是仅当事务已提交且行已更改时才更新。@ott-我相信只有在事务提交后才会更新。
xid
s似乎在数据是经过修改的(不太可能,但必须加以考虑),因此我不确定是否应该依赖它们。xid的总结,因此您必须知道如何比较它们的规则(例如,使用
age()
函数)。如果您更新一行,您将立即在该行的新版本上看到新的
xmin
,而不仅仅是在事务结束后。时间戳通常不是一个选项。我也可以在SQLite中这样做。版本控制应该是数据库的任务,而不是应用程序的任务。