java - 使 Spring Hibernate 线程安全。最好的安慰

标签 java spring multithreading hibernate server

我搜索了多种方法和解决方案来使 Spring hibernate 到安全线程。我是 Spring 和 Hibrenate 的新手,我无法独自做出这个决定。

我找到了这些选项:

  1. 使用 hibernate locking “破坏”任何与其他事务发生冲突的事务,并避免数据库出现错误数据。这有一个缺点,因为事务将不会被执行,并且完成这些请求将更加复杂

  2. 简单地在一个线程中运行所有事务(至少是所有更新),该线程将是“ExcuterThred”,并且他共享所有这些事务将按串行顺序执行。这样就不会有transactoin冲突的机会,但是这个解决方案使你的数据库Spring服务器依赖于一个线程,它可以通过useig regular java thread来实现,也许很大 like this ,或使用thread local

  3. 使dao同步(或至少所有更新方法),也不会发生transactoin冲突,但可以跟踪服务器。

更重要的是,在我的服务器中,任何客户端都有用户,并且任何用户都有唯一的 ID。我想到了更多一个选项:为了共享,任何客户端都只能在同一时间发送一个请求(这使得数据库不同)。 (我现在可以,因为我可以使用唯一的ID),如果客户端这样做,我将响应并发错误,并且他可以重试信件。 这将是选项 4

如果您有更多选择,请告诉我。

非常感谢,非常欢迎任何帮助或解释

最佳答案

对于大多数使用 Hibernate 和 Spring 的应用程序来说,这会带来什么好处?

我推测对于大多数应用程序来说,设计实际上会造成净损失,因为您描述的场景实际上更多的是一种极端情况,现有的锁定策略以及与其他技术堆栈的集成可以轻松实现缓解这些问题。

您应该始终首先尝试使用乐观锁定

过去,我使用过一种解决方案,在该解决方案中维护实体的缓存副本,将其用作用户开始操作时数据库所拥有内容的快照。当用户将更改发布回服务器时,我修改该实体的第二个实例,然后尝试保存该实例。每当 Hibernate 因乐观锁定异常而失败时,我可以将返回的数据库快照与原始缓存副本进行比较,并决定是否可以重试该操作,断言是否无法重试或在 X 次重试尝试后。

这绝对是额外的代码吗?但这是特定于用例和业务案例的额外代码。有些情况下,我想快速失败。在其他情况下,我可能想重试,而在其他情况下,我可能只是允许最后更改它的人获胜。

如果更新必须序列化,您可以考虑使用代理解决方案,例如 JMS 队列或类似的解决方案,您可以将更新操作发布到单个处理程序并在其中执行。这使您可以根据需要扩展应用程序,并避免在应用程序中嵌入后台线程。但这确实意味着您的应用程序必须处理最终一致性,因为如果该队列有积压,则更新可能需要几秒钟或几分钟的时间才能反射(reflect)在您的应用程序中。如果您也使用二级缓存 (2LC),还要了解其含义。

老实说,我认为您正在尝试过度设计一些已经有经过验证的解决方案来准确处理您所关心的问题的东西。是否有努力去做正确的事情,绝对。但复杂的解决方案也不只是几行代码:P。

关于java - 使 Spring Hibernate 线程安全。最好的安慰,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42600318/

相关文章:

java - 如何处理这个二叉树中的公共(public)/私有(private)对?

java - 即使数据库已关闭,如何使应用服务器启动?

c# - 创建一个 c# windows 服务来轮询数据库

java - openshift mysql 连接 NumberFormatException 与 Tomcat 7 (JBoss EWS 2.0)

java - run方法之外的同步方法

c++ - 对象被移动到另一个线程后不能简单地删除它吗?

java - 如何阅读冗长的 :GC output?

Java.lang.IllegalStateException : Failed to parse JaCoCo XML report: jacoco. exec

java - 运行 Flutter 应用时出现 "Could not connect to the Gradle daemon"和 IP 地址问题

mysql - MySQL8 的 Hibernate 方言