Spring Boot声明式事务管理示例 - Go语言中文社区

Spring Boot声明式事务管理示例


视频讲解地址:(预留:待上传……)
让我们开始吧:

什么是数据库事务?

数据库事务是访问并可能修改数据库内容的单个逻辑工作单元。
在这里插入图片描述
让我们检查一下mysql数据库:

  • 为mysql数据库打开两个单独的窗口
    在这里插入图片描述
  • 在一个mysql窗口中,创建一个名为test的数据库,并在‘s其中创建一个名为employee的表
    create database test;
    create table employee(id varchar(10), name varchar(10));
    -【【【【【【【【【【【【
  • 默认情况下,事务是针对mysql数据库自动提交的。 我们将使用以下命令禁用自动提交:
    SET autocommit = 0;
    在这里插入图片描述
  • 在第一个mysql窗口中,使用以下插入命令-如果现在使用第二个mysql窗口,请对employee表进行选择,我们将看不到任何记录。这是因为事务仍未在第一个mysql窗口中提交。
    在这里插入图片描述
  • 现在,我们在第一个MySQL命令中使用commit命令。如果现在使用第二个mysql窗口,请选择employee表,我们将看到两条记录
    在这里插入图片描述

应用程序中的事务:

现在让我们将应用程序事务用于Spring Boot JDBC项目。
我们将开发一个用于员工管理的Spring Boot + JDBC项目。它将有3个服务

  • EmployeeService-服务将执行员工操作
  • HealthInsuranceService-该服务将执行员工健康保险业务
  • OrganizationService-服务将执行组织级别的操作,例如员工加入和退出。它利用EmployeeService和HealthInsuranceService

OrganizationService员工加入工作流程
在这里插入图片描述
OrganizationService员工退出工作流程

在这里插入图片描述
应用程序事务是应用程序操作的序列,被应用程序视为单个逻辑单元。对于我们的应用程序,joinOrganization方法将被视为一项完整的事务。 joinOrganization由两个动作组成-

  • 持久化员工信息
  • 持久化健康保险信息
    在这里插入图片描述
    如果由于任何原因上述任何一个操作失败,则另一个操作也应回滚。因此,如果插入了“员工信息”,但假设由于某些原因而导致HealthInsurance失败,则还应该回滚“员工信息”。这意味着逻辑工作单元是全部或全部。 exitOrganization方法的情况与此类似,它将被视为一个工作单元。

在这里插入图片描述
最初,我们将不使用任何事务管理。默认情况下,spring boot事务是自动提交。但这不是一个好习惯,我们将在下一节中了解原因。

程序细节展示

1、工程结构在这里插入图片描述

2、Pom文件的内容:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.javainuse</groupId>
	<artifactId>boot-jdbc</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>boot-jdbc</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.1.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>


</project>

3、修改配置文件:(替换成自己的数据库服务器的ip,用户名和密码)

spring.datasource.url=jdbc:mysql://数据库服务器的ip/bootdb?createDatabaseIfNotExist=true&autoReconnect=true&useSSL=false
spring.datasource.username= 数据库用户名
spring.datasource.password= 密码
spring.datasource.platform=mysql
spring.datasource.initialization-mode=always
logging.level.org.springframework=DEBUG

4、这是初始化脚本,由Spring Boot JDBC-开始运行

DROP TABLE IF EXISTS employee;
DROP TABLE IF EXISTS employeeHealthInsurance;


CREATE TABLE employee (
  empId VARCHAR(10) NOT NULL,
  empName VARCHAR(100) NOT NULL
);

CREATE TABLE employeeHealthInsurance (
  empId VARCHAR(10) NOT NULL,
  healthInsuranceSchemeName VARCHAR(100) NOT NULL,
  coverageAmount VARCHAR(100) NOT NULL
);

5、定义Model类Employee,它将代表Employee详细信息

package com.javainuse.model;

public class Employee {

	private String empId;
	private String empName;

	public String getEmpId() {
		return empId;
	}

	public void setEmpId(String empId) {
		this.empId = empId;
	}

	public String getEmpName() {
		return empName;
	}

	public void setEmpName(String empName) {
		this.empName = empName;
	}

	@Override
	public String toString() {
		return "Employee [empId=" + empId + ", empName=" + empName + "]";
	}

}

6、创建用于执行Employee操作的EmployeeDAO接口,如下所示:

package com.javainuse.dao;

import com.javainuse.model.Employee;

public interface EmployeeDao {
	void insertEmployee(Employee cus);

	void deleteEmployeeById(String empid);
}

7、创建实现EmployeeDAO接口的EmployeeDAOImpl,如下所示。
Spring Boot将在类路径和mysql上检测spring-jdbc,并将自动为我们创建一个数据源和一个JdbcTemplate。因为这样的基础结构现在可用,并且我们没有专用的配置,所以还将为我们创建一个DataSourceTransactionManager。

package com.javainuse.dao.impl;

import javax.annotation.PostConstruct;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.stereotype.Repository;

import com.javainuse.dao.EmployeeDao;
import com.javainuse.model.Employee;

@Repository
public class EmployeeDaoImpl extends JdbcDaoSupport implements EmployeeDao {

	@Autowired
	DataSource dataSource;

	@PostConstruct
	private void initialize() {
		setDataSource(dataSource);
	}

	@Override
	public void insertEmployee(Employee emp) {
		String sql = "INSERT INTO employee " + "(empId, empName) VALUES (?, ?)";
		getJdbcTemplate().update(sql, new Object[] { emp.getEmpId(), emp.getEmpName() });
	}

	@Override
	public void deleteEmployeeById(String empid) {
		String sql = "DELETE FROM employee WHERE empId = ?";
		getJdbcTemplate().update(sql, new Object[] { empid });

	}
}

8、定义Model类EmployeeHealthInsurance,它将代表Employee Health Insurance详细信息-

package com.javainuse.model;

public class EmployeeHealthInsurance {

	private String empId;
	private String healthInsuranceSchemeName;
	private int coverageAmount;

	public String getEmpId() {
		return empId;
	}

	public void setEmpId(String empId) {
		this.empId = empId;
	}

	public String getHealthInsuranceSchemeName() {
		return healthInsuranceSchemeName;
	}

	public void setHealthInsuranceSchemeName(String healthInsuranceSchemeName) {
		this.healthInsuranceSchemeName = healthInsuranceSchemeName;
	}

	public int getCoverageAmount() {
		return coverageAmount;
	}

	public void setCoverageAmount(int coverageAmount) {
		this.coverageAmount = coverageAmount;
	}

}

9、创建执行以下医疗保险业务的HealthInsuranceDao-

package com.javainuse.dao;

import com.javainuse.model.EmployeeHealthInsurance;

public interface HealthInsuranceDao {
	void registerEmployeeHealthInsurance(EmployeeHealthInsurance employeeHealthInsurance);

	void deleteEmployeeHealthInsuranceById(String empid);
}

10、创建实现HealthInsuranceDao的EmployeeHealthInsuranceDAOImpl,如下所示:

package com.javainuse.dao.impl;

import javax.annotation.PostConstruct;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.stereotype.Repository;

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

@Repository
public class HealthInsuranceDaoImpl extends JdbcDaoSupport implements HealthInsuranceDao {

	@Autowired
	DataSource dataSource;

	@PostConstruct
	private void initialize() {
		setDataSource(dataSource);
	}

	@Override
	public void registerEmployeeHealthInsurance(EmployeeHealthInsurance emp) {
		String sql = "INSERT INTO employeeHealthInsurance "
				+ "(empId, healthInsuranceSchemeName, coverageAmount) VALUES (?, ?,?)";
		getJdbcTemplate().update(sql,
				new Object[] { emp.getEmpId(), emp.getHealthInsuranceSchemeName(), emp.getCoverageAmount() });
	}

	@Override
	public void deleteEmployeeHealthInsuranceById(String empid) {
		String sql = "DELETE FROM employeeHealthInsurance WHERE empId = ?";
		getJdbcTemplate().update(sql, new Object[] { empid });

	}
}

11、创建用于执行员工操作的EmployeeService接口,如下所示:

package com.javainuse.service;

import com.javainuse.model.Employee;

public interface EmployeeService {
	void insertEmployee(Employee emp);

	void deleteEmployeeById(String empid);
}

12、创建实现EmployeeService的EmployeeServiceImpl,如下所示:

package com.javainuse.service.impl;

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

import com.javainuse.dao.EmployeeDao;
import com.javainuse.model.Employee;
import com.javainuse.service.EmployeeService;

@Service
public class EmployeeServiceImpl implements EmployeeService {

	@Autowired
	EmployeeDao employeeDao;

	@Override
	public void insertEmployee(Employee employee) {
		employeeDao.insertEmployee(employee);
	}

	@Override
	public void deleteEmployeeById(String empid) {
		employeeDao.deleteEmployeeById(empid);
	}

}

13、创建HealthInsuranceService接口,如下所示:

package com.javainuse.service;

import com.javainuse.model.EmployeeHealthInsurance;

public interface HealthInsuranceService {
	void registerEmployeeHealthInsurance(EmployeeHealthInsurance employeeHealthInsurance);

	void deleteEmployeeHealthInsuranceById(String empid);
}

14、创建HealthInsuranceServiceImpl,以实现HealthInsuranceService,如下所示:

package com.javainuse.service.impl;

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

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

@Service
public class HealthInsuranceServiceImpl implements HealthInsuranceService {

	@Autowired
	HealthInsuranceDao healthInsuranceDao;

	@Override
	public void registerEmployeeHealthInsurance(EmployeeHealthInsurance employeeHealthInsurance) {
		healthInsuranceDao.registerEmployeeHealthInsurance(employeeHealthInsurance);
	}

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

}

15、创建OrganisationService接口,如下所示:

package com.javainuse.service;

import com.javainuse.model.Employee;
import com.javainuse.model.EmployeeHealthInsurance;

public interface OrganizationService {

	public void joinOrganization(Employee employee, EmployeeHealthInsurance employeeHealthInsurance);

	public void leaveOrganization(Employee employee, EmployeeHealthInsurance employeeHealthInsurance);

}

16、创建实现OrganizationService的OrganizationServiceImpl。它利用了EmployeeService和HealthInsuranceService。

package com.javainuse.service.impl;

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

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
public class OrganzationServiceImpl implements OrganizationService {

	@Autowired
	EmployeeService employeeService;

	@Autowired
	HealthInsuranceService healthInsuranceService;

	@Override
	public void joinOrganization(Employee employee, EmployeeHealthInsurance employeeHealthInsurance) {
		employeeService.insertEmployee(employee);
		healthInsuranceService.registerEmployeeHealthInsurance(employeeHealthInsurance);
	}

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

17、最后,如下创建Spring Boot Main类:

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.OrganizationService;

@SpringBootApplication
public class SpringBootJdbcApplication {

	public static void main(String[] args) {
		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(20000);

		organizationService.joinOrganization(emp, employeeHealthInsurance);
	}
}

18、运行本工程:
如果现在运行该

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/u011500356/article/details/106920266
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢