Spring Boot-事务隔离教程
Posted 独孤文彬
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Boot-事务隔离教程相关的知识,希望对你有一定的参考价值。
在上一个教程 -Spring Boot事务管理示例中, 我们了解了什么是事务并实现了声明式事务管理。同样在 上一教程中,我们实现了各种事务传播类型。在本教程中,我们将了解什么是事务隔离及其不同类型。
视频讲解地址:(预留:待上传……)
让我们开始吧:
什么是事务隔离?
当两个事务同时作用于同一数据库实体时,事务隔离定义数据库状态。它涉及锁定数据库记录。因此,当一个事务在数据库实体上工作时,它描述了数据库的行为或状态,然后其他并发事务试图同时访问/编辑同一数据库实体。
ANSI / ISO标准定义了四个隔离级别。 隔离是ACID(原子性,一致性,隔离性,耐久性)的一种。 因此,事务隔离级别不是特定于Spring框架的。使用Spring,我们可以更改隔离级别以适合我们的业务逻辑。
在使用Spring实现隔离级别之前,让我们首先了解数据库级别的隔离级别。
我们将创建一个表名称为employee的表,并使用该表尝试了解隔离级别-
CREATE TABLE employee (
empId VARCHAR(10) NOT NULL,
empName VARCHAR(100) NOT NULL
);
我用于实现隔离级别的一些SQL命令是
//Show existing transaction isolation level if mysql version >= 8
SELECT @@TRANSACTION_ISOLATION;
//Show existing transaction isolation level if mysql version < 8
SELECT @@TX_ISOLATION;
//Set transaction isolation level to serializable. Using same syntax
//we can set it to other isolation level.
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
//By default auto commit is enabled for mysql transaction. So we will disable it.
SET AUTOCOMMIT=0;
//Start transaction
BEGIN
//Commit transaction
COMMIT
以下是事务隔离级别的类型-
- 可串行化
如果两个事务同时执行,则好像是串行执行事务,即仅第一个事务被提交,然后第二个事务被执行。这是完全隔离。因此,正在运行的事务永远不会受到其他事务的影响。但是,这可能会导致问题,因为性能会很低,并且可能会发生死锁。
- REPEATABLE_READ
如果两个事务正在同时执行- 在提交第一个事务之前,第二个事务不能更改现有记录,但是可以添加新记录。提交第二个事务后,新添加的记录将反映在仍未提交的第一个事务中。对于MySQL,默认隔离级别为REPEATABLE_READ。
但是,使用mysql时,REPEATABLE READ隔离级别的行为有所不同。使用MYSQL时,我们看不到第二笔交易提交的新添加的记录。
- READ_COMMITTED
如果两个事务同时执行- 在提交第一个事务之前,可以更改现有记录,也可以通过第二个事务更改新记录。 提交第二个事务后,新添加的记录和更新的记录也会反映在仍未提交的第一个事务中。
- READ_UNCOMMITTED
如果两个事务同时执行-在提交第一个事务之前,可以更改现有记录,也可以通过第二个事务更改新记录。即使未提交第二个事务,新添加的以及更新的记录也会反映在仍未提交的第一个事务中。
摘要 - 脏读-假设有两个事务-事务A和事务B同时运行。如果事务A修改了一条记录但没有提交。事务B读取该记录,但随后事务A再次回滚该记录的更改并提交。因此,事务B的值有误。
- 不可重复读取,假设有两个事务-事务A和事务B同时运行。如果事务A读取某些记录。事务B在提交事务A之前先修改这些记录。因此,如果事务A再次读取这些记录,它们将是不同的。因此,相同的select语句会导致不同的现有记录。
- 幻读,假设有两个事务-事务A和事务B同时运行。如果事务A读取某些记录。事务B在提交事务A之前添加了更多此类记录。因此,如果事务A再次读取,则记录将比前一个select语句更多。因此,相同的select语句会导致显示不同的数字记录,因为也会添加新记录。
使用Spring Boot实现事务隔离
在Spring Boot中使用事务隔离时,默认的事务隔离是基础数据库的事务隔离。因此,对于我们的Spring Boot应用程序,由于我们使用的是MySQL数据库,因此默认事务隔离为REPEATABLE_READ。在上一个教程 -Spring Boot事务管理示例中, 我们了解了什么是事务并实现了声明式事务管理。我们将修改此代码。我们可以如下更改事务隔离级别:
package com.javainuse.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
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
public class OrganzationServiceImpl implements OrganizationService
@Autowired
EmployeeService employeeService;
@Autowired
HealthInsuranceService healthInsuranceService;
@Override
// Using Transactional annotation we can define any isolation level supported by the underlying database.
@Transactional(isolation = Isolation.SERIALIZABLE)
public void joinOrganization(Employee employee, EmployeeHealthInsurance employeeHealthInsurance)
employeeService.insertEmployee(employee);
healthInsuranceService.registerEmployeeHealthInsurance(employeeHealthInsurance);
@Override
@Transactional
public void leaveOrganization(Employee employee, EmployeeHealthInsurance employeeHealthInsurance)
employeeService.deleteEmployeeById(employee.getEmpId());
healthInsuranceService.deleteEmployeeHealthInsuranceById(employeeHealthInsurance.getEmpId());
以上是关于Spring Boot-事务隔离教程的主要内容,如果未能解决你的问题,请参考以下文章