Spring Boot事务管理-事务回滚示例

在先前的教程中,我们已经实现了 Spring Boot事务管理示例 -我们看到了什么是事务并实现了声明式事务管理。在以前的教程 -Spring Boot事务-了解事务传播中, 我们还研究了什么是传播以及使用Spring Boot的不同类型。在下一个教程中,我们将研究 什么是使用Spring Boot的事务隔离。 在Spring Boot事务管理示例中, 我们已经看到应用程序事务是一系列应用程序操作,这些操作被应用程序视为单个逻辑单元。
Spring Boot事务管理-事务回滚示例_第1张图片
对于应用程序事务,如果任何操作失败,则所有其他操作都会回滚。在先前的事务管理示例中,我们通过引发未经检查的异常来测试了回滚。

但是,在实时方案中,将抛出已检查的异常。这些是基于某种逻辑的业务异常。
那么,如果发生“检查异常”,我们的交易将如何表现?在发生检查异常的情况下,即使我们使用了事务注释,先前执行的事务也不会自动回滚。 我们需要通知应用程序如何在发生检查异常时处理回滚。这可以通过RollbackFor注释实现。

视频讲解地址:(预留:待上传……)
让我们开始吧:
我们将修改我们 先前为事务管理创建的代码。
我们将创建一个称为InvalidInsuranceAmountException的自定义检查异常。根据我们的业务逻辑,如果保险额度小于零,则应抛出此异常。
Spring Boot事务管理-事务回滚示例_第2张图片
创建自定义异常 如下-

package com.javainuse.service.impl;

public class InvalidInsuranceAmountException extends Exception {

	private static final long serialVersionUID = 1L;

	public InvalidInsuranceAmountException(String cause) {
		super(cause);
	}

}	

HealthInsuranceService接口为registerEmployeeHealthInsurance方法引发此异常。

package com.javainuse.service;

import com.javainuse.model.EmployeeHealthInsurance;
import com.javainuse.service.impl.InvalidInsuranceAmountException;

public interface HealthInsuranceService {
void registerEmployeeHealthInsurance(EmployeeHealthInsurance employeeHealthInsurance)
throws InvalidInsuranceAmountException;

	void deleteEmployeeHealthInsuranceById(String empid);
}

在registerEmployeeHealthInsurance的HealthInsuranceServiceImpl类中,我们进行了一项检查,以验证保险金额是否小于零。如果是,则抛出InvalidInsuranceAmountException。

package com.javainuse.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.javainuse.dao.HealthInsuranceDao;
import com.javainuse.model.EmployeeHealthInsurance;
import com.javainuse.service.HealthInsuranceService;

@Service
@Transactional
public class HealthInsuranceServiceImpl implements HealthInsuranceService {

	@Autowired
	HealthInsuranceDao healthInsuranceDao;

	@Override
	public void registerEmployeeHealthInsurance(EmployeeHealthInsurance employeeHealthInsurance)
	throws InvalidInsuranceAmountException {
		
	if (employeeHealthInsurance.getCoverageAmount() < 0) {
		throw new InvalidInsuranceAmountException("Coverage Amount Should not be negative");
		}
	healthInsuranceDao.registerEmployeeHealthInsurance(employeeHealthInsurance);
	}

	@Override
	public void deleteEmployeeHealthInsuranceById(String empid) {
		healthInsuranceDao.deleteEmployeeHealthInsuranceById(empid);
	}

}

joinOrganization方法的OrganizationService接口将引发InvalidInsuranceAmountException。

package com.javainuse.service;

import com.javainuse.model.Employee;
import com.javainuse.model.EmployeeHealthInsurance;
import com.javainuse.service.impl.InvalidInsuranceAmountException;

public interface OrganizationService {

	public void joinOrganization(Employee employee, EmployeeHealthInsurance employeeHealthInsurance)
	 throws InvalidInsuranceAmountException;

	public void leaveOrganization(Employee employee, EmployeeHealthInsurance employeeHealthInsurance);
}

在对HealthInsuranceService类进行调用的OrganzationServiceImpl中,我们将InvalidInsuranceAmountException记录到日志中并再次抛出。这是因为我们希望调用客户端知道发生了什么异常。

package com.javainuse.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.javainuse.model.Employee;
import com.javainuse.model.EmployeeHealthInsurance;
import com.javainuse.service.EmployeeService;
import com.javainuse.service.HealthInsuranceService;
import com.javainuse.service.OrganizationService;

@Service
@Transactional
public class OrganzationServiceImpl implements OrganizationService {

	@Autowired
	EmployeeService employeeService;

	@Autowired
	HealthInsuranceService healthInsuranceService;

	@Override
	@Transactional
	public void joinOrganization(Employee employee, EmployeeHealthInsurance employeeHealthInsurance)
	throws InvalidInsuranceAmountException {
	employeeService.insertEmployee(employee);
	try {
		healthInsuranceService.registerEmployeeHealthInsurance(employeeHealthInsurance);
		} catch (InvalidInsuranceAmountException e) {
		throw new InvalidInsuranceAmountException("Exception is thrown");
		}
	}

	@Override
	public void leaveOrganization(Employee employee, EmployeeHealthInsurance employeeHealthInsurance) {
		employeeService.deleteEmployeeById(employee.getEmpId());
		healthInsuranceService.deleteEmployeeHealthInsuranceById(employeeHealthInsurance.getEmpId());
	}
}

最后,在SpringBootJdbcApplication中,我们抛出InvalidInsuranceAmountException。

package com.javainuse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

import com.javainuse.model.Employee;
import com.javainuse.model.EmployeeHealthInsurance;
import com.javainuse.service.EmployeeService;
import com.javainuse.service.OrganizationService;
import com.javainuse.service.impl.InvalidInsuranceAmountException;

@SpringBootApplication
public class SpringBootJdbcApplication {
	
	
	@Autowired
	EmployeeService employeeService;

	public static void main(String[] args) throws InvalidInsuranceAmountException {
		ApplicationContext context = SpringApplication.run(SpringBootJdbcApplication.class, args);
		OrganizationService organizationService = context.getBean(OrganizationService.class);

		
		Employee emp= new Employee();
		emp.setEmpId("emp1");
		emp.setEmpName("emp1");
		
		EmployeeHealthInsurance employeeHealthInsurance= new EmployeeHealthInsurance();
		employeeHealthInsurance.setEmpId("emp1");
		employeeHealthInsurance.setHealthInsuranceSchemeName("premium");
		employeeHealthInsurance.setCoverageAmount(0);
	
		organizationService.joinOrganization(emp, employeeHealthInsurance);
	}
}

如果现在运行该应用程序-我们看到由于employeeHealthService中的异常而没有回退employeeService事务。

Spring Boot事务管理-事务回滚示例_第3张图片

在数据库中,我们看到雇员表的插入尚未回滚,
Spring Boot事务管理-事务回滚示例_第4张图片

但是事实并非如此。为了实现针对检查异常的回滚,我们需要使用Rollbackfor Annotation指定它。

package com.javainuse.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.javainuse.model.Employee;
import com.javainuse.model.EmployeeHealthInsurance;
import com.javainuse.service.EmployeeService;
import com.javainuse.service.HealthInsuranceService;
import com.javainuse.service.OrganizationService;

@Service
@Transactional
public class OrganzationServiceImpl implements OrganizationService {

@Autowired
EmployeeService employeeService;

@Autowired
HealthInsuranceService healthInsuranceService;

@Override
@Transactional(rollbackFor = InvalidInsuranceAmountException.class)
public void joinOrganization(Employee employee, EmployeeHealthInsurance employeeHealthInsurance)
throws InvalidInsuranceAmountException {
	employeeService.insertEmployee(employee);
	try {
	healthInsuranceService.registerEmployeeHealthInsurance(employeeHealthInsurance);
	} catch (InvalidInsuranceAmountException e) {
	throw new InvalidInsuranceAmountException("Exception is thrown");
	}
}

@Override
public void leaveOrganization(Employee employee, EmployeeHealthInsurance employeeHealthInsurance) {
	employeeService.deleteEmployeeById(employee.getEmpId());
	healthInsuranceService.deleteEmployeeHealthInsuranceById(employeeHealthInsurance.getEmpId());
	}
}

现在再次运行该应用程序。我们看到由于employeeHealthService中的异常而回退了employeeService事务。
Spring Boot事务管理-事务回滚示例_第5张图片
在数据库中,我们看到员工表的插入已回滚-

Spring Boot事务管理-事务回滚示例_第6张图片

你可能感兴趣的:(-------【微服务】)