java - Spring @Transactional 只读

标签 java spring hibernate spring-boot spring-data-jpa

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

有了这个依赖

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

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

@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

最佳答案

BeanS call a transactional=read-only Bean1, which does a lookup and calls transactional=read-write Bean2 which saves a new object.

> 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
> 

Nothing is committed to the database.

Now change Bean2 @Transactional annotation to add 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); 
   } 

关于java - Spring @Transactional 只读,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44496333/

相关文章:

java - 使用 Swing 组件作为内容的自定义 Java 工具提示未显示

java - hibernate get id=0 批量更新从更新 [0] 返回了意外的行数;实际行数 : 0; expected: 1

java - 拥有用于发送和接收 UDP 数据报的专用 DatagramSocket 是否有(性能)优势?

java - Hibernate 查询中的重复项

java - Spring 拒绝缺少供应商 header 的请求(自定义 MIME 类型)

java - @Autowired vs @Required on setter

java - 能够通过hibernate连接到postgres但是不能通过执行查询获取数据

mysql - 使用 CrudRepository 删除带有集合的实体时,Hibernate-envers 抛出异常

java - 我想通过java从主机和jmx端口获取指标

java - 在Java中将BMP图像转换为PNG或JPG,无需将整个图像加载到内存中