hibernate中脏读的工作原理

hibernate中脏读的工作原理,hibernate,dirtyread,Hibernate,Dirtyread,根据Manning的Java持久化与Hibernate: 如果一个事务读取另一个事务所做的更改,则会发生脏读 尚未提交的事务。这很危险,, 因为其他事务所做的更改可能会在以后滚动 返回,第一个事务可能会写入无效数据 如果从数据库检索记录,则在持久状态下创建了相应的对象,并且所做的任何更改都将首先写入持久对象,从而使其变脏 现在我的问题是,如果某个其他事务正在读取同一条记录,那么它是从持久状态(即一级缓存,目前是脏的)读取该记录,还是从数据库检索该记录。一级缓存不是跨事务共享的。除了扩展持久性上下

根据Manning的Java持久化与Hibernate:

如果一个事务读取另一个事务所做的更改,则会发生脏读 尚未提交的事务。这很危险,, 因为其他事务所做的更改可能会在以后滚动 返回,第一个事务可能会写入无效数据

如果从数据库检索记录,则在持久状态下创建了相应的对象,并且所做的任何更改都将首先写入持久对象,从而使其变脏


现在我的问题是,如果某个其他事务正在读取同一条记录,那么它是从持久状态(即一级缓存,目前是脏的)读取该记录,还是从数据库检索该记录。

一级缓存不是跨事务共享的。除了扩展持久性上下文之外,使用的最常见模式是每个事务与单个会话/持久性上下文关联,并且具有自己的一级缓存,该缓存仅针对该事务进行跟踪

实际上,“脏读”是数据库事务的一个属性,而不是通常的休眠。当一个事务读取另一个尚未提交的事务所做的更改时,称为脏读。使用这种类型的事务非常危险,因为读取的数据可能会回滚

无论进行什么更改,都会首先写入持久对象,从而使其变脏


您在上面一行中所说的是,已经对对象进行了更改(但更改尚未发送到数据库,因为ORM(如Hibernate)会将刷新sql延迟到事务结束)。因此,更改后的对象现在变脏了,但不能对事务进行同样的处理,因为没有向数据库发送insert/update/delete从应用程序的角度来看,hibernate读取的数据的对象表示形式可以通过使用setter进行更改,因此对象或数据变为“脏”,需要在事务结束时刷新到数据库,否则应用程序可能实际上决定不提交。Hibernate的主要任务是跟踪此已更改(“脏”)状态,并在事务结束时生成适当的插入/更新/删除。因此,该脏数据是初始读取状态和同一事务中发生更改后的状态(如果有)之间的差异。

因此,您的意思是,如果我们试图在同一事务中获取相同的记录(即具有相同id),则会发生脏数据读取。