spring-data postgres事务隔离问题

时间:2016-11-12 23:03:13

标签: java postgresql hibernate spring-data

我有两个实体:MessageSessionMessage@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表中,该怎么办?

换句话说,我们有:

  1. 交易开始
  2. 正在阅读记录
  3. 使用SessionSession 循环处理
  4. sessionClose个实例 - newSessionOpen
  5. 交易结束
  6. 如果某个其他进程请求在2到4或2和3之间或其中某个地方请求打开Session怎么办? 那么它会打开Session吗?旧的还是新的? 我使用postgres和@Transactional Spring注释。

1 个答案:

答案 0 :(得分:1)

假设您的问题中的“会话”始终是指您创建的实体。

根据这个:https://www.postgresql.org/docs/9.1/static/transaction-iso.html postgres的默认隔离级别可以防止脏读。因此,在该事务提交(即结束)之前,没有其他事务能够看到您的第一个事务中所做的任何更改。

根据相同的源,您可以将事务隔离级别设置为uncommited。在这种情况下,第二个事务可能能够看到第一个事务所做的更改,尽管第一个事务尚未提交。请注意,虽然对实体的更改不会立即写入数据库,但仅在事务结束前刷新,在select选择执行之前明确调用flush或配置。因此,尽管您的数据库设置可能允许脏读,但由于JPA / Hibernate

的行为,您可能不会遇到它们