我设计了一个基于Web的项目。
我正在使用Mysql数据库。我将使用hibernate在java中执行所有持久性逻辑。所有客户端操作都将在javascript中完成。
我的问题是,
如果两个用户试图在不同的地方同时更新同一记录。
最初用户1通过提供与单个对象相关的完整信息并称为保存信息方法进行更新。
在另一端,User-2通过提供部分信息和称为保存信息的方法来更新相同的记录。
如果首先保存User-1信息,则User-2信息将覆盖第一个给定信息。因此,一些信息可能会丢失哪个用户1,但他不知道某些东西被释放。
请提出一些建议来克服这个问题。
答案 0 :(得分:1)
您需要考虑的是数据的locking策略。使用Hibernate,默认情况下你没有锁定(a.k.a.Ostrich lock或“last save wins”)。粗略地说,另外两个选项是乐观锁定和悲观锁定。
乐观锁定意味着您不会阻止用户同时编辑数据,但是如果编辑失败,您将通知用户,因为数据是从数据库加载后从其他地方保存的。
悲观锁定意味着您可以防止多个用户同时编辑数据。这是一种更复杂的锁定形式,通常既不实用也不必要。
可以从Hibernate documentation找到有关实施锁定策略的更多信息。您应该选择哪种策略取决于您的应用程序以及是否需要经常编辑相同信息的许多用户。
答案 1 :(得分:1)
我建议你使用乐观锁。基本上这个技术是在表中有一个字段告诉Hibernate你的版本是什么,因此较小版本的对象是否试图覆盖较大版本的数据hibernate会引发异常。此版本控制字段通常是一个数字字段,休眠随每个更新或日期字段而增加。流程类似于:
1 - 记录被插入基地。在这一点上"版本"字段设置为零。
2 - X用户使用版本0查询记录。
3 - Y用户使用版本0查询记录。
4 - Y用户更新注册表信息。此时,hibernate会自动将记录版本增加为1。
5 - X用户更新版本0上的信息并尝试保存。此时,hibernate发现该记录已经在版本1中,该版本大于用户X正在使用的版本,因为它会引发异常,说明问题并且不允许覆盖最新信息。
要实现此策略,只需在表格中创建一个数字字段,然后应用@Version:
@Version
@Column(name = "version")
private Integer version;
答案 2 :(得分:0)
在用户2更新数据库之前,您可以检查数据库中的信息(例如行)是否与用户2到达更新/编辑页面时的信息相同。例如您可以在用户到达页面时对该行执行SELECT,并在用户进行更改后(即在更新行之前)再次执行SELECT,并在更新数据库之前对其进行比较。
如果行相同,则没有更改。如果行不同,则其他人编辑了它。