我有两个实体:Message
和Session
。
Message
与@ManyToOne
的关系Session
。
我有一个Spring Data存储库和操作A:
@Query("select c from Messages c where c.session.mode=0 and c.field=5")
List<Messages> findMessages();
然后我处理找到的数据
messages.ForEach(message->{
Session session = message.getSession();
sessionClose(session);
newSessionOpen();
})
和其他服务类我有
Session session=findOpenedSession();
问题是:
如果操作A在事务中以及在它开始之后和结束之前的其他服务将会请求打开Session
或将尝试将记录插入到Message
表中,该怎么办?
换句话说,我们有:
Session
和Session
循环处理sessionClose
个实例 - newSessionOpen
如果某个其他进程请求在2到4或2和3之间或其中某个地方请求打开Session
怎么办?
那么它会打开Session
吗?旧的还是新的?
我使用postgres和@Transactional
Spring注释。
答案 0 :(得分:1)
假设您的问题中的“会话”始终是指您创建的实体。
根据这个:https://www.postgresql.org/docs/9.1/static/transaction-iso.html postgres的默认隔离级别可以防止脏读。因此,在该事务提交(即结束)之前,没有其他事务能够看到您的第一个事务中所做的任何更改。
根据相同的源,您可以将事务隔离级别设置为uncommited。在这种情况下,第二个事务可能能够看到第一个事务所做的更改,尽管第一个事务尚未提交。请注意,虽然对实体的更改不会立即写入数据库,但仅在事务结束前刷新,在select选择执行之前明确调用flush或配置。因此,尽管您的数据库设置可能允许脏读,但由于JPA / Hibernate
的行为,您可能不会遇到它们