mysql 如何在应用层正确实现乐观锁?

dphi5xsq  于 5个月前  发布在  Mysql
关注(0)|答案(2)|浏览(46)

我有点困惑,为什么乐观锁定实际上是安全的。如果我在更新时检查检索时的版本,如果操作系统在提交实际发生之前发出中断并交换进程,似乎我仍然可以有两个请求进入更新块。例如:

latestVersion = vehicle.getVersion();
if (vehicle.getVersion() == latestVersion) {
    // update record in database
} else {
    // don't update record 
}

字符串
在这个例子中,我试图在一个Java应用程序中手动使用乐观锁定,而不使用JPA / Hibernate。然而,似乎两个请求可以同时进入if块。你能帮助我理解如何正确地做到这一点吗?对于上下文,我也使用Java Design Patterns网站作为例子。

x0fgdtte

x0fgdtte1#

嗯……这是乐观的部分。乐观的是它是安全的。如果你必须确定它是安全的,那就不乐观了。
你展示的例子肯定容易受到竞争条件的影响,这不仅是因为线程调度,还因为事务隔离级别。
MySQL中的一个简单的读取,在默认的事务隔离级别REPEATABLE READ中,将读取在事务启动时提交的数据。
而更新数据将作用于更新时提交的数据。如果其他并发会话在此期间更新了数据库中的行并提交了它,那么您的更新将“看到”最新提交的行,而不是您的get方法查看的行。
避免竞争条件的方法是不要乐观。相反,* 强制 * 独占访问记录。Doveryai, no proveryai.
如果您只有一个应用示例,则可以为此使用临界区。
如果您有多个应用示例,则临界区无法协调其他示例,因此您需要在数据库中进行协调。您可以使用悲观锁定来完成此操作。要么使用locking read query读取记录,要么使用MySQL's user-defined locks

xiozqbni

xiozqbni2#

如果你的意思是在REST接口上实现某种安全性,请看看这篇文章https://sookocheff.com/post/api/optimistic-locking-in-a-rest-api/这篇文章没有提到的是posaerodom来强制执行条件PUT/PATCH,甚至是HTTP 428错误代码。
你依赖版本的方法对我来说似乎是合法的。另外,你需要处理某种乐观锁定异常,并将其转换为412代码。

相关问题