Spring Boot和Spring数据jpa中的事务管理

Mic*_*ölm 4 spring-data-jpa spring-boot

Altough事务管理工作Spring Data Repositories创建自己的事务并暂停活动事务.

我有以下Spring应用程序:

申请类:

@SpringBootApplication
@EnableTransactionManagement
public class SpringbootTxApplication {... }
Run Code Online (Sandbox Code Playgroud)

服务类:

@Service
public class EntityService {
    ...
    public void addEntityWithoutTransaction(MyEntity myEntity) {
        log.debug("addEntityWithoutTransaction start");
        myEntityRepository.save(myEntity);
        log.debug("addEntityWithoutTransaction end");
    }

    @Transactional
    public void addEntityTransaction(MyEntity myEntity) {
        log.debug("addEntityTransaction start");
        myEntityRepository.save(myEntity);
        log.debug("addEntityTransaction end");
    }
}
Run Code Online (Sandbox Code Playgroud)

在执行我的EntityServiceTest时执行每个方法一次并在跟踪中有spring事务日志,我得到以下输出:

... TRACE ... o.s.t.i.TransactionInterceptor           : Getting transaction for [de.miwoe.service.EntityService.addEntityTransaction]
... DEBUG ... de.miwoe.service.EntityService           : addEntityTransaction start
... TRACE ... o.s.t.i.TransactionInterceptor           : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
... TRACE ... o.s.t.i.TransactionInterceptor           : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
... DEBUG ... de.miwoe.service.EntityService           : addEntityTransaction end
... TRACE ... o.s.t.i.TransactionInterceptor           : Completing transaction for [de.miwoe.service.EntityService.addEntityTransaction]
Run Code Online (Sandbox Code Playgroud)

... DEBUG ... de.miwoe.service.EntityService           : addEntityWithoutTransaction start
... TRACE ... o.s.t.i.TransactionInterceptor           : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
... TRACE ... o.s.t.i.TransactionInterceptor           : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
... DEBUG ... de.miwoe.service.EntityService           : addEntityWithoutTransaction end
Run Code Online (Sandbox Code Playgroud)

显然根据日志,@ Transactional-Annotation在addEntityTransaction中工作,但存储库仍然创建自己的事务.

为什么?官方文档(https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions)描述如果它已经存在,它不应该开始新的.

(有时候,"约定优于配置"似乎更像是对"约定优于配置"的激怒......)

我错过了什么吗?

(完整的代码也可以在这里找到:https://github.com/miwoe/springboot-tx)

xyz*_*xyz 9

你的问题(要点):

... TRACE ... o.s.t.i.TransactionInterceptor           : Getting transaction for [de.miwoe.service.EntityService.addEntityTransaction]
... DEBUG ... de.miwoe.service.EntityService           : addEntityTransaction start
... TRACE ... o.s.t.i.TransactionInterceptor           : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
... TRACE ... o.s.t.i.TransactionInterceptor           : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
... DEBUG ... de.miwoe.service.EntityService           : addEntityTransaction end
... TRACE ... o.s.t.i.TransactionInterceptor           : Completing transaction for [de.miwoe.service.EntityService.addEntityTransaction]
Run Code Online (Sandbox Code Playgroud)

显然根据日志,@ Transactional-Annotation在addEntityTransaction中工作,但存储库仍然创建自己的事务.

答:您在一次实际交易中工作.

当启动调用服务spring启动新事务并设置时TransactionStatus.isNewTransaction = true,当你调用dao方法spring时检查该方法也是事务性的并为dao创建第二个事务,BUT设置为第二个事务TransactionStatus.isNewTransaction = false.如果你为dao方法/类设置required_new只在这种情况下它被标记为TransactionStatus.isNewTransaction = true. 在提交时,仅提交第一个事务(物理).如果您标记第二个事务,它将在提交时被忽略,并且第一个事务将被提交.

AbstractPlatformTransactionManager

    if (status.isNewTransaction()) {
       if (status.isDebug()) {
            logger.debug("Initiating transaction commit");
        }
        doCommit(status);
    }
Run Code Online (Sandbox Code Playgroud)

您可以签入调试模式.

要点:您在一个可能被标记为提交或回滚的事务中工作.在TRACE中,您会看到有关Spring事务的详细信息,对于您而言,在物理事务中创建了多少逻辑事务并不重要.对于传播级别为REQUIRED的事务,您有保证,如果从另一个事务方法调用事务方法,则只创建一个物理事务,并且一个事务提交或回滚.

PROPAGATION_REQUIRED

当传播设置为PROPAGATION_REQUIRED时,将为应用该设置的每个方法创建逻辑事务范围.每个这样的逻辑事务范围可以单独确定仅回滚状态,外部事务范围在逻辑上独立于内部事务范围.当然,在标准PROPAGATION_REQUIRED行为的情况下,所有这些范围将映射到同一物理事务.因此,内部事务范围中的仅回滚标记集确实会影响外部事务实际提交的机会(正如您所期望的那样).


Kyl*_*son 5

存储库方法是@Tranactional因为您正在利用该JpaRepository接口并允许框架为您实现该接口.

它默认选择SimpleJpaRepository使用@Transactional.看看来源,你会看到它的使用位置.