Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 具有乐观锁定的活动记录模式-更新前读取与在应用程序中存储版本?_Java_Activerecord_Jdbc_Optimistic Locking - Fatal编程技术网

Java 具有乐观锁定的活动记录模式-更新前读取与在应用程序中存储版本?

Java 具有乐观锁定的活动记录模式-更新前读取与在应用程序中存储版本?,java,activerecord,jdbc,optimistic-locking,Java,Activerecord,Jdbc,Optimistic Locking,我尝试使用Java/JDBC和MySQL以及用于并发处理的乐观锁定来实现活动记录模式 现在,对于表中的所有记录,我有一个“version\u number”字段,它在每次更新后都会递增 似乎有两种策略可以实现这一点: 应用程序在请求数据时还存储每个对象(即记录)的相应版本号。更新时,版本号将“发送到”数据层,该数据层在更新…设置…查询乐观锁定时使用 应用程序不存储版本号,只存储对象的某些部分(与整行数据相反)。要使乐观锁定成功,数据层(活动记录)需要首先从数据库中获取“行”,获取版本号,然后启动

我尝试使用Java/JDBC和MySQL以及用于并发处理的乐观锁定来实现活动记录模式

现在,对于表中的所有记录,我有一个“version\u number”字段,它在每次更新后都会递增

似乎有两种策略可以实现这一点:

  • 应用程序在请求数据时还存储每个对象(即记录)的相应版本号。更新时,版本号将“发送到”数据层,该数据层在更新…设置…查询乐观锁定时使用
  • 应用程序不存储版本号,只存储对象的某些部分(与整行数据相反)。要使乐观锁定成功,数据层(活动记录)需要首先从数据库中获取“行”,获取版本号,然后启动相同的更新…设置…WHERE查询以更新记录
  • 在前者中,有“第一次抓取”,然后是更新。在后一种情况下,您确实有一个“首次获取”,但在更新之前也有一个获取

    问题是:根据设计,哪种方法更好?将所有数据(包括版本号)存储在web应用程序的前端(Javascript/HTML)中是否可以/安全/正确?还是在更新之前先进行读操作会更好


    是否有一种“正确的方法”来实现此设计?我不确定当前的active record实现如何处理这个问题(Ruby、Play、ActiveJDBC等),如果我要在JDBC中“原始”实现它,在这种情况下,什么是正确的设计决策?

    这既不是性能问题,也不是安全问题,这两种方法在功能上不同,实现的目标也不同

    第一种方法是乐观地在用户的整个“思考时间”内锁定行。如果用户1加载屏幕,则用户2进行更改,用户1的更改将失败,他们将看到一个错误,即他们正在查看过期数据

    使用第二种方法,您只能防止竞争请求线程之间的交叉写入。用户1可以加载一个页面,然后用户2进行更改,然后当用户1点击提交时,他们的更改将通过并吹出用户2的更改。用户1可能已经根据过时的信息做出了决定,并且永远不会知道


    这是一个问题,你希望哪种行为符合你的业务规则,而不是一种或另一种在技术上是“正确的”。它们都是有效的,它们做不同的事情

    实现了版本1。对于版本2,您可能会引入竞争条件

    我认为这里有一个混乱-我不会在整个思考时间内锁定行,也不会发生丢失更新!我只是没有明确表示,如果更新失败,我会抛出异常并通知用户!!我不确定你提到的两个场景中的任何一个会如何发生?在场景1中,你乐观地将行锁定以等待思考时间。当用户开始思考时,您知道版本号是什么,并且确保他们完成时版本号是相同的。在场景2中,您只在提交时的末尾检查版本号。这可能与他们开始思考时不同,因此丢失了update.tl;dr选项1是执行“正常”乐观锁定的正确方法。选项2导致最后一个wins并发情况,实际上只检查服务器中的线程交叉,而不是用户认为的交叉。