繁体   English   中英

Spring数据JPA和事务管理

[英]Spring data JPA and transaction management

在我的spring服务中,我调用了两个spring数据存储库方法

@Service
public class ClientService {
    public void updateClientByIdAndKey(final Integer id, final String key) {
        final Client client = clientRepository.findByIdAndKey(id, key);
        // .. Update client details
        client.save(client);
   }
}

现在我的查询与事务管理有关。 据我了解并看过代码,spring存储库使用@Transactional为其方法启用了事务。 对于选择操作,它具有readonly = true。

我对事务的理解是,当执行select操作然后创建事务然后为保存操作创建另一个事务,因为对于select操作事务是readOnly = true。

我希望在单个事务中执行读写操作。 如果我上面的理解是正确的那么@Transactional over service方法updateClientByIdAndKey将在一个事务中运行,这是我的意图还是将在一个事务中执行两个操作?

如果我在这里遗漏任何东西,请告诉我。

@Transactional的ReadOnly属性默认为false。 通过使用Transactional简单地注释方法,读取/选择操作和更新操作都将在单个事务中发生。 如果您将属性更改为true,我猜您不会发生两个事务,而是在尝试更新时会引发异常。

编辑:如果方法未使用Transactional注释,则两个操作都不会在单个事务中执行。 实际上,根据您如何配置ORM,在执行更新时可能会抛出异常,因为连接将在select之后关闭。

当您将@Transactional注释添加到updateClientByIdAndKey方法时,spring将只创建一个读写事务(除非您使用PROPAGATION_REQUIRES_NEW或其他类型的传播findByIdAndKey/save方法上添加额外的@Transactional注释。当您向@Transactional添加readOnly = true@Transactional spring会将Hibernate会话中的flushMode设置为NEVER 。这意味着你不能执行任何创建,更新,删除操作。

方法findByIdAndKey不需要做COMMIT(存储对数据库的更改),应该注释为

@Transactional(readOnly = true)

方法updateClientByIdAndKey应该使用

@Transactional

updateClientByIdAndKey中,只使用一个读写事务,除非您的嵌套方法findByIdAndKey定义了

@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)

在这种情况下,您显式创建一个没有意义的新(只读)事务。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM