简体   繁体   中英

Spring data JPA and transaction management

In my spring service I call two spring data repository methods

@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. For select operations it has 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.

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?

Please let me know if I am missing anything here.

The ReadOnly property of @Transactional is defaulted to false. By simply annotating the method with Transactional both the read/select operation and the update operation will happen in a single transaction. 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.

EDIT: If the method is not annotated with Transactional both operations will not execute in a single transaction. 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.

当您将@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

@Transactional(readOnly = true)

method updateClientByIdAndKey should use

@Transactional

in updateClientByIdAndKey just one read-write Transaction is used unless your nested method findByIdAndKey defines a

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

In this case you are explicitly creating a new (readonly) Transaction that doesn't make sense.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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