spring - Spring boot JPA repository committing code even if @Transactional placed in Service layer
问题描述
See below spring boot code
I have used JPA repository.
- Controller.
- Service.
- Repository
BaseController
package com.controller;
import com.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class BaseController {
@Autowired
private StudentService studentService;
@GetMapping(value = "/addStudent", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseEntity<String> base() {
studentService.save();
return new ResponseEntity<String>("SUCCESS", HttpStatus.OK);
}
}
StudentService.java
package com.service;
import com.model.Student;
import com.repository.StudentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service("studentService")
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentRepository studentRepository;
@Override
@Transactional
public Student save() {
Student student = new Student();
student.setFirstName("ABC");
student.setLastName("PQR");
studentRepository.save(student);
int i = 10 / 0; //Error code
return student;
}
}
StudentRepository
package com.repository;
import com.model.Student;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository("studentRepository")
public interface StudentRepository extends CrudRepository<Student, Long> {
public List<Student> findAll();
}
Application.properties
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
#maximum number of milliseconds that a client will wait for a connection
spring.datasource.hikari.connection-timeout = 20000
#minimum number of idle connections maintained by HikariCP in a connection pool
spring.datasource.hikari.minimum-idle= 10
#maximum pool size
spring.datasource.hikari.maximum-pool-size= 10
#maximum idle time for connection
spring.datasource.hikari.idle-timeout=10000
# maximum lifetime in milliseconds of a connection in the pool after it is closed.
spring.datasource.hikari.max-lifetime= 1000
#default auto-commit behavior.
spring.datasource.hikari.auto-commit =false
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.jdbcUrl=jdbc:mysql://localhost:3306/demo?autoReconnect=true&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.show-sql=true
spring.jpa.properties..hibernate.format_sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.ddl-auto=update
After executing save method from StudentRepository, data get inserted immediately into database. no rollback or any other isolation levels are working in StudentServiceImpl.java even if Error code is there. I have tried to set
"spring.datasource.hikari.auto-commit =true"
setting value true, Placed @Transaction at top of the StudentServiceImpl.java class but still it didn't worked.
解决方案
- 您不需要弄乱任何hikari 设置,当然也不需要使用 autoCommit(true),因为这会禁用事务。删除所有这些属性。
- 您的代码中的“错误”在哪里?Spring 在抛出未经检查的异常(未检查的异常或错误)时回滚,我在您的代码中看不到这一点。
- 你期望什么行为?我觉得很好。
推荐阅读
- python - 创建一个数组,其中一个字母重复给定次数,由另一个数组给出
- c - 如何将内存数据从指针复制到数组 ASSEMBLY 8086
- c++ - 在 C++ 中初始化类变量浮点数组
- java - 在 Android 9、API 28 上使用 JSON 的 HttpURLConnection
- c++ - 静脉模拟终止调用 openssl ECDSA_SIG_get0 函数
- java - Micronaut:使用 Consul 依赖构建本机映像不起作用
- java - AWS API Gateway - 在 Java 中使用 Spring RestTemplate 访问 API 时连接超时,使用 Postman 可以正常工作
- java - 在Java中将素数从一个数组复制到另一个数组的方法
- html - 在某个高度后更改元素的宽度
- excel - 如何根据来自另一个单元格的值锁定一个单元格