`@Transactional` 回滚在 Spring Boot 应用中不起作用?

huangapple go评论102阅读模式
英文:

@Transactional rollback is not working in spring boot application?

问题

我有一个需求需要将一些员工数据插入到db2数据库中以下是代码

@Log4j2
@Service
@Transactional
public class EmployeeServiceImpl extends EmployeeService {

@Autowired
private EmployeeDataRepository employeeDataRepository;

@Override
@Transactional(rollbackOn = {DataAccessException.class})
public void insertEmployeeData(List<Employee> employeeList) {
 try {
     employeeDataRepository.insertEmployeeData(employeeList);
    } catch (DataAccessException ex) {
      log.error("在插入数据到数据库时出现异常: {}", ex.getMessage());
    }
}
}

@Log4j2
@Repository
public class EmployeeDataRepositoryImpl implements EmployeeDataRepository {

@Autowired
private DataSource dataSource;

@Value("${db.schema}")
private String schema;

@Override
public void insertEmployeeData(List<Employee> employeeList) {
   this.jdbcInsert = new SimpleJdbcInsert(dataSource).withTableName("Employee");
   for(Employee emp : employeeList) {
    Map<String,Object> parameters = new HashMap<String,Object>();
      parameters.put("name", emp.name);
      parameters.put("age", emp.age);
      parameters.put("dateOfJoining", emp.dateOfJoining);
      parameters.put("address", emp.address);
      parameters.put("salary", emp.salary);
      jdbcInsert.execute(parameters);
      log.info("创建记录 姓名 = " + name + " 年龄 = " + age + " 加入日期 = "+dateOfJoining);
	  }
      return;
}
 
} 

使用Spring数据源属性配置并将数据源注入到EmployeeDataRepositoryImpl类中。我使用SimpleJdbcInsert将数据插入到db2表中。为了进行事务处理,我在方法上使用了@Transactional(rollbackOn = {DataAccessException.class})。当逐条插入数据时,如果在数据库层面出现问题,应该进行回滚,但实际上并没有发生。我也尝试在类级别上添加注解,但没有成功。请告诉我是否有遗漏的地方?


<details>
<summary>英文:</summary>
I am having a requirement where i need to insert some employee data into db2 database and below is the code for that :

@Log4j2
@Service
@Transactional
public class EmployeeServiceImpl extends EmployeeService{

@Autowired
private EmployeeDataRepository employeeDataRepository;

@Override
@Transactional(rollbackOn = {DataAccessException.class})
public void insertEmployeeData(List<Employee> employeeList){
try{
employeeDataRepository.insertEmployeeData(employeeList);
}catch(DataAccessException ex){
log.error("Exception whie inserting data in db {}",ex.getMessage());
}
}


@Log4j2
@Repository
public class EmployeeDataRepositoryImpl implements EmployeeDataRepository{

@Autowired
private DataSource dataSource;

@Value("${db.schema}")
private String schema;

@Override
public void insertEmployeeData(List<Employee> employeeList){
this.jdbcInsert = new SimpleJdbcInsert(dataSource).withTableName("Employee");
for(Employee emp : employeeList){
Map<String,Object> parameters = new HashMap<String,Object>();
parameters.put("name", emp.name);
parameters.put("age", emp.age);
parameters.put("dateOfJoining", emp.dateOfJoining);
parameters.put("address", emp.address);
parameters.put("salary", emp.salary);
jdbcInsert.execute(parameters);
log.info("Created Record Name = " + name + " Age = " + age + " dateOfJoining = "+dateOfJoining);
}
return;
}

}

using spring datasource properties datasource is configured and injected into `EmployeeDataRepositoryImpl` class. I am using `SimpleJdbcInsert` to insert data into db2 table. For transnational handling i am using 
`@Transactional(rollbackOn = {DataAccessException.class})` on method. When the data is inserted one by one then if something goes wrong at db level then it should rollback but eventually its not happening. Also i tried putting annotation at class level but there is no luck. Please let me know if i am missing anything ?
</details>
# 答案1
**得分**: 5
你在这里混淆了一些事情。
1. 如果在你的 @Transactional 方法中出现(运行时)异常,Spring 会回滚你的事务。
2. 你正在捕获 DataAccessException 异常,因此阻止了回滚。
3. 也不需要在 rollbackOn 中指定异常。
你的代码应该像这样,这就足够了。
```java
@Transactional
public void insertEmployeeData(List<Employee> employeeList){
employeeDataRepository.insertEmployeeData(employeeList);
}

有关 @Transactional 如何工作的更多信息,请查看此链接。

英文:

You are having a couple of things mixed up here.

  1. Spring rolls your transaction back, if a (Runtime)exception bubbles through your @Transactional method.
  2. You are catching the DataAccessException exception, hence preventing the rollback.
  3. There is also no need to specify the exception in rollbackOn.

Your code should read like this, this is enough.

@Transactional
public void insertEmployeeData(List&lt;Employee&gt; employeeList){
employeeDataRepository.insertEmployeeData(employeeList);
}

For more information on how @Transactional works, see this link.

答案2

得分: 2

尝试使用rollBackFor而不是rollBackOn

根据以下链接:
https://github.com/spring-projects/spring-boot/issues/12709

英文:

Try rollBackFor instead of rollBackOn

As per below link:
https://github.com/spring-projects/spring-boot/issues/12709

huangapple
  • 本文由 发表于 2020年3月4日 08:29:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/60517469.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定