Spring @Transactional 只读

3

我有一个基本的SpringBoot应用程序。使用Spring Initializer,内嵌Tomcat,Thymeleaf模板引擎,并打包为可执行的JAR文件。

使用以下依赖项:

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

我创建了这个声明为readOnly的服务:

@Service
@Transactional(readOnly = true)
public class TimeLapseService {

    @Autowired
    TimeLapseRepository timeLapseRepository;

    public Set<TimeLapse> findAllByCompanyId(long companyId) {
        return timeLapseRepository.findAllByCompanyId(companyId);
    }

    public Iterable<TimeLapse> findAll (User user) {

        if (user.isAdmin()) {
            return timeLapseRepository.findAll();
        } else {
            return timeLapseRepository.findAllByCompanyId(user.getCompany().getId());
        }   

    }

    public void createTimeLapse (TimeLapse timeLapse) {
        timeLapseRepository.save (timeLapse);
    }

}

并且

public interface TimeLapseRepository extends CrudRepository<TimeLapse, Long> {
....
}

据我所知,由于该服务被声明为只读,因此创建新服务不应该将任何内容保存到数据库中,但它会在表中创建一行数据。
timeLapseService.createTimeLapse(timeLapse24h);

JPA 属性:

spring.datasource.url=jdbc:h2:mem:testdb;MODE=MySQL;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
hibernate.dialect=org.hibernate.dialect.H2Dialect

你是如何检查是否有新记录的?例如,从数据库客户端中看到了吗?请同时添加你所拥有的JPA配置。 - GabiM
可以在方法级别重写类级别的事务。 - Anand Sinha
为什么不尝试重写您的保存方法以覆盖只读属性,像这样 - Pradeep
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) public void createTimeLapse (TimeLapse timeLapse) { timeLapseRepository.save (timeLapse); } - Pradeep
在这里清晰地解释了。 - Pradeep
https://stackoverflow.com/questions/8604931/how-to-use-readonly-when-transactional-is-on-class-level - Pradeep
1个回答

5
BeanS调用一个事务性只读的Bean1,该Bean进行查找并调用事务性读写的Bean2来保存一个新对象。
> Bean1 starts a read-only tx. 31 09:39:44.199 [pool-1-thread-1] DEBUG
> o.s.orm.jpa.JpaTransactionManager - Creating new transaction with name
> [nz.co.vodafone.wcim.business.Bean1.startSomething]:
> PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly; ''

> 
> Bean 2 pariticipates in it. 31 09:39:44.230 [pool-1-thread-1] DEBUG
> o.s.orm.jpa.JpaTransactionManager - Participating in existing
> transaction
> 

没有任何内容被提交到数据库。

现在将Bean2的@Transactional注释更改为添加propagation=Propagation.REQUIRES_NEW

> Bean1 starts a read-only tx. 31 09:31:36.418 [pool-1-thread-1] DEBUG
> o.s.orm.jpa.JpaTransactionManager - Creating new transaction with name
> [nz.co.vodafone.wcim.business.Bean1.startSomething]:
> PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly; ''
> 
> Bean2 starts a new read-write tx 31 09:31:36.449 [pool-1-thread-1]
> DEBUG o.s.orm.jpa.JpaTransactionManager - Suspending current
> transaction, creating new transaction with name

除非您按照以下方式进行,否则它将被持久化。
    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
    public void createTimeLapse (TimeLapse timeLapse)
   { 
    timeLapseRepository.save (timeLapse); 
   } 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接