简体   繁体   English

Spring数据JPA和事务管理

[英]Spring data JPA and transaction management

In my spring service I call two spring data repository methods 在我的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);
   }
}

Now my query is related to the transaction management. 现在我的查询与事务管理有关。 As far as I understand and have seen code, spring repositories have transactions enabled using @Transactional for its methods. 据我了解并看过代码,spring存储库使用@Transactional为其方法启用了事务。 For select operations it has readonly=true. 对于选择操作,它具有readonly = true。

My understanding about transaction is that when select operation is executed then a transaction is created and then for the save operation another transaction is created, since for select operation transaction is readOnly=true. 我对事务的理解是,当执行select操作然后创建事务然后为保存操作创建另一个事务,因为对于select操作事务是readOnly = true。

I wanted both read and write operations to be executed in a single transaction. 我希望在单个事务中执行读写操作。 If my understanding above is correct then having @Transactional over service method updateClientByIdAndKey will run both in one transaction which is my intention or will spring execute both operation in one transaction? 如果我上面的理解是正确的那么@Transactional over service方法updateClientByIdAndKey将在一个事务中运行,这是我的意图还是将在一个事务中执行两个操作?

Please let me know if I am missing anything here. 如果我在这里遗漏任何东西,请告诉我。

The ReadOnly property of @Transactional is defaulted to false. @Transactional的ReadOnly属性默认为false。 By simply annotating the method with Transactional both the read/select operation and the update operation will happen in a single transaction. 通过使用Transactional简单地注释方法,读取/选择操作和更新操作都将在单个事务中发生。 Should you change the property to true I am guessing you will not have two transactions occurring, but instead an exception will be raised when the update is attempted. 如果您将属性更改为true,我猜您不会发生两个事务,而是在尝试更新时会引发异常。

EDIT: If the method is not annotated with Transactional both operations will not execute in a single transaction. 编辑:如果方法未使用Transactional注释,则两个操作都不会在单个事务中执行。 In fact, depending on how you how configured your ORM, an exception may be thrown when executing the update as the connection will have been closed following the select. 实际上,根据您如何配置ORM,在执行更新时可能会抛出异常,因为连接将在select之后关闭。

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

method findByIdAndKey don't need to do COMMIT (store changes to database) and should be annotated as 方法findByIdAndKey不需要做COMMIT(存储对数据库的更改),应该注释为

@Transactional(readOnly = true)

method updateClientByIdAndKey should use 方法updateClientByIdAndKey应该使用

@Transactional

in updateClientByIdAndKey just one read-write Transaction is used unless your nested method findByIdAndKey defines a updateClientByIdAndKey中,只使用一个读写事务,除非您的嵌套方法findByIdAndKey定义了

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

In this case you are explicitly creating a new (readonly) Transaction that doesn't make sense. 在这种情况下,您显式创建一个没有意义的新(只读)事务。

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

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