当前位置: 首页 > 知识库问答 >
问题:

Spring Data对于第三方查询来说是数据安全的吗?

司寇旺
2023-03-14

我对我读到的SpringData/Hibernate的黑匣子持久性相关内容感到困惑——主要是查询缓存和刷新。

据我了解:

缓存查询:< br> Spring data不直接在数据库的事务中运行查询,而是将它们缓存在内存中,直到某个时刻(尽可能晚的时刻)——即数据库中的事务提交。这是因为性能原因——因此代码不必在每次调用< code>repository时都到达数据库。

刷新:
当需要与数据库交互时-例如接收生成的(数字id)或默认值-code可以刷新存储库以直接在数据库上运行查询(仍在单个事务中)。这使得通过外键等进行数据绑定成为可能…

我需要知道以下几点:

  • Spring 数据对于第三方数据操作(例如其他应用程序、数据库控制台,..)是否完全数据安全?我的意思是 - 与其他客户端的交互/刷新是否存在不一致的情况?
  • 如果没有,实现此目的的设置是什么?
  • Micronaut数据的工作方式是否相同?

共有2个答案

谢和颂
2023-03-14

为了澄清这个问题,我将添加一个伪代码来可视化问题。
考虑在数据库上设置READ_COMMITED级别,并且每个方法的开头的数字=5。

@Transactional
fun read() {
    val number1 = myRepository.findById(1).number
    //now another client commits number = 10
    val number2 = myRepository.findById(1).number
}

@Transactional
fun write() {
    val number1 = myRepository.updateNumberById(id=1, number=10).number
    //now another client commits number = 7
    val number2 = myRepository.findById(1).number
}

每种方法中 number1 和 number2 的值是什么,Hibernate 和 DB 之间的流程是什么?

左丘昕
2023-03-14

在回答你的问题之前,让我做几个澄清。

Spring数据是一把大伞,可以覆盖许多数据存储。比如有Spring Data JDBC,直接和JDBC司机沟通;Spring Data Redis提供了对Redis服务器的存储库访问;与您的问题最相关的是Spring Data JPA,它使用JPA实现(默认为Hibernate)通过JPA与您的数据库进行交互。

您所指的缓存是HiberNate的第一级缓存,持久性上下文。它实际上是JPA实体的缓存。在刷新时,HiberNate将获取“保存的”实体(合并/持久化,通过调用Spring Data存储库上的#保存方法触发)并生成适当的INSERT/UPDATE/DELETE查询来更新数据库中的数据。

Spring数据对于第三方数据操作(例如,其他应用程序、数据库控制台、..)?我的意思是,与其他客户端的交易活动/刷新是否可能存在不一致?

听起来你在问隔离,答案将取决于你认为隔离级别中的“数据安全”。大多数数据库默认为“READ COMMITTED”,其中来自已提交并发事务的数据可以在当前事务中读取,就好像未提交的更改从未发生过一样。我假设这是你将坚持的级别隔离。更严格的隔离级别需要更仔细的考虑,以避免过度锁定。

在READ COMMITTED隔离级别下,Hibernate所做的缓存(就读取现象而言)与通过非JPA应用程序/数据库控制台等执行相同语句时没有区别。这是因为事务只读取提交的数据,所以延迟INSERTs/UPDATE没有关系,因为它们的新状态只有在COMMIT之后才可见,而不管 / 本身是何时由数据库执行的。

实体的缓存是使用持久性上下文完成的。持久性上下文绑定到Hibernate会话。Hibernate会话在Spring事务开始时打开,并在事务结束时关闭。因此,修改后的实体的缓存不会超过数据库事务的寿命。请注意,在视图中打开会话有几个例外,但仍然存在对实体的修改在会话结束时被刷新/提交到数据库的情况。

如果没有,有哪些设置可以实现这一点?

同样,“数据安全”程度取决于数据库的默认隔离级别。如果您认为需要与默认隔离级别不同的隔离级别,可以通过以下几种方式进行更改:

    < li >如果允许,更改整个数据库的隔离级别。这将取决于您使用的DBMS,因此您需要找到各自DBMS的文档。 < li >更改Hibernate的已配置事务隔离级别,我将参考另一个SO回答,其中也包括隔离级别的描述 < li >使用Spring的< code>@Transactional注释设置隔离级别。例如,可以通过用< code > @ Transactional(Isolation = Isolation)注释事务性方法来设置可序列化的隔离级别。可序列化)。有关其他选项和说明,请参见Javadoc。

Micronaut数据的工作方式相同吗?

我没有使用过Micronaut数据,但据我所知,答案也将取决于你如何使用Micronaut数据。Micronaut Data JDBC(以及Spring Data JDBC)没有实体缓存。我的理解是,Micronaut Data JPA仍然只是委托给Hibernate,在这种情况下,是的,Hibernat仍将使用持久上下文执行实体缓存。

也就是说,正如我之前提到的,由于该隔离级别的行为,大多数情况下,这在已读提交隔离级别上不会引起关注。

 类似资料:
  • 数据安全说明 数据传输 及策数据传输包含 SDK 采集数据传输 和 系统 API 数据传输: SDK 采集数据传输 是指及策 SDK 采集数据通过网络发送到及策服务器,该过程我们使用了业内通用的 https 加密协议来防止数据被恶意截获解析; 系统 API 数据传输 是指和及策产品和客户自助开发的数据分析系统进行数据对接时所用到的数据传输接口,该过程我们也使用 https 加密协议进行传输,并进行

  • 我正在将.csv导入Mysql,如下所示: …引发以下错误: "对于第63行的“注释”列,数据太长" 我看着第63行。csv,而“评论”的长度为115。 create语句似乎没问题(带有): 在将其标记为副本之前,请注意: 这个StackOverflow解决方案显然不适合:我已经将< code >字符集utf8添加到< code>LOAD DATA sql中。 另一个StackOverflow解决

  • 在我的工作中,传统的做法是不安全地将参数连接到查询字符串中来形成SQL查询。当然,这会导致SQL注入漏洞。这并不被认为是一个大问题,因为发生这种情况的所有Java软件都运行在封闭的网络上,所有用户都被认为是可信的。此外,查询是从具有数据库访问权限的客户端应用程序执行的,因此从技术上讲,用户无论如何都可以执行恶意查询。 尽管如此,它计划在数据库层的新版本中支持准备好的语句。同时,我在现有的数据库层上

  • 我有我的班级电影: 和我的控制器方法: 我得到一个错误: Servlet.service()的servlet[springDispatcher]在上下文与路径[/web编程]抛出异常[请求处理失败;嵌套异常org.springframework.dao.DataIntegrityViolationException:无法执行语句;SQL[n/a];嵌套异常是org.hibernate.except

  • 问题内容: 我想知道是否可以在@Query批注中包含子查询(org.springframework.data.jpa.repository.Query;) 我在第一个子查询括号上得到QuerySyntaxException。 这是我的查询 谢谢! 问题答案: 不可以,JPQL查询的select子句中不能包含子查询。 JPQL在WHERE和HAVING子句中支持子查询。它可以(至少)是ANY,SOM

  • 问题内容: 假设我有一个客户表: 此表也 没有 主键。但是,并且对于任何给定都 应该 是唯一的。 该表包含许多重复的客户并不少见。为了避免重复,使用以下查询仅隔离唯一的客户: 幸运的是,该表格传统上包含准确的数据。也就是说,从来没有任何冲突或任何冲突。但是,假设有冲突的数据确实将其放入表中。我希望编写一个将失败的查询,而不是为有问题的查询返回多行。 例如,我尝试此查询没有成功: 有没有办法使用标准