Java Web应用程序:存储库中数据的并行更改

Java Web应用程序:存储库中数据的并行更改,java,spring,Java,Spring,我目前正在设计一个web应用程序(适度现代化),它可以轻松地处理数据库中的数据。我已经在考虑潜在的问题了 假设用户登录到web应用程序并从存储库加载一些数据。(S) 他改变了数据,然后想把它写回数据库 如何以标准化的方式防止以下情况: (S) 他登录了两次,并且已经在第二次会话中保存了一些数据,这些数据将在第一次会话中保存时丢失 其他一些用户加载了数据,现在正在对其进行更改,他们可能会覆盖我们的更改 我不想说2阶段提交,我也不打算推出我自己的版本。防止同一用户登录两次(用户单例),再加上严格

我目前正在设计一个web应用程序(适度现代化),它可以轻松地处理数据库中的数据。我已经在考虑潜在的问题了

假设用户登录到web应用程序并从存储库加载一些数据。(S) 他改变了数据,然后想把它写回数据库

如何以标准化的方式防止以下情况:

  • (S) 他登录了两次,并且已经在第二次会话中保存了一些数据,这些数据将在第一次会话中保存时丢失
  • 其他一些用户加载了数据,现在正在对其进行更改,他们可能会覆盖我们的更改
我不想说2阶段提交,我也不打算推出我自己的版本。防止同一用户登录两次(用户单例),再加上严格的权限管理可以解决第一个问题。但是,如果业务需求允许多个代理查看和更改相同的数据,我仍然不知所措


如果阅读时的假设成立,是否有差异化库/算法来测试需要在写入之前写入的数据?对于更大的商业应用程序,这通常是如何解决的?

在大多数(我指的是几乎所有)应用程序中,这是使用类似Oracle、MySQL、PostgreSQL的

我会在两种主要策略中选择:

  • 乐观锁
  • 悲观锁
乐观锁定:在存储库(数据库)中保存一个版本(编号)和对象的id。保存新对象之前,请检查要覆盖的旧对象的版本。如果版本与已编辑对象的版本不匹配,则中止保存并向用户报告存储库中的对象已更改。如果版本匹配,则用新对象覆盖旧对象并增加版本

悲观锁定:在用户开始更改对象之前锁定对象。如果对象已锁定,则显示消息,表示当前对象正在由其他用户编辑。 这可以在单个事务中使用DB锁定和Statefull bean来完成,也可以使用单独的使用定义字段来完成

悲观锁定的实现更加复杂,但它提供了更好的用户体验,因为如果发生乐观锁定异常,它会阻止用户输入数据,然后再次输入数据


有关更多信息,请参阅。

在web应用程序上下文中,这是否仍然需要分布式事务协议?@0xCAFEBABE:当然不需要。人们之所以花很多钱说甲骨文是因为它为你做的。被接受的答案中提到的JPAAPI也将委托给后台数据库。请在这里阅读这篇文章。它讨论了现代DBs是如何进行并发控制的:我可以看到,通过“乐观锁定”中的“You”,您指的是一个bean,这使事情变得更加简单。这似乎是一个合理的解决方案。