概述
文章目录
- 一、事务概念
- 二、spring事务
- 三、事务操作(注解实现声明式事务管理)
- 3.1、在spring配置文件中配置事务管理器
- 3.2、在spring配置文件中开启事务注解
- 3.3、在service类上面(或者service类里面方法上)添加事务注解
- 四、声明式事务管理参数配置
- 4.1、propagation:事务传播行为
- 4.2、ioslation:事务隔离级别
- 4.3、timeout:超时时间
- 4.4、readOnly:是否只读
- 4.5、rollbackFor:回滚
- 4.6、noRollbackFor:不回滚
一、事务概念
1、什么是事务
事务是数据库操作最基本的单元,逻辑上一组操作,要么都成功,如果有一个失败,则所有操作都失败
经典场景:银行转账
2、事物的四个特性(ACID)
原子性、一致性、隔离性、持久性
3、引出事务操作
(1)数据库建表account,并插入数据
pom依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.7.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.20</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.3.0.RELEASE</version>
</dependency>
</dependencies>
核心配置文件application.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context ="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 开启组件扫描-->
<!-- 2、扫描上层-->
<context:component-scan base-package="com.lu"></context:component-scan>
<!-- 数据库连接池。
destroy-method="close"作用是当数据库连接不使用的时候,就把该连接重新放到数据池中,方便下次使用调用.
xml中:&要用 & 转义-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/spring-crud?userSSL=true&
useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
<!--JdbcTemplate对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--注入dataSourceDefault-->
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
(2)创建service,dao完成对象创建和注入关系
UserDao类
public interface UserDao {
void addMoney();
void reduceMoney();
}
UserDaoImpl类
@Repository
public class UserDaoImpl implements UserDao{
@Autowired
private JdbcTemplate jdbcTemplate;
public void addMoney() {
String sql = "update account set money = money-? where username=?";
jdbcTemplate.batchUpdate(sql,"100","lucy");
}
public void reduceMoney() {
String sql = "update account set money = money+? where username=?";
jdbcTemplate.batchUpdate(sql,"100","tom");
}
}
UserService类
@Service
public class UserService {
//注入dao
@Autowired
private UserDao userDao;
//转账方法
public void accountMoney(){
//lucy少100
userDao.reduceMoney();
//tom多100
userDao.addMoney();
}
}
测试类TestAccount
public class TestAccount {
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("application.xml");
UserService userService = context.getBean("userService",UserService.class);
userService.accountMoney();
}
}
3、正常执行上边程序,是没问题的。但是,如果在步骤中间,有异常,就可能导致一个成功、一个失败的问题,进而导致钱数错误。
//转账方法
public void accountMoney(){
//lucy少100
userDao.reduceMoney();
//模拟异常
int i= 10/0;
//tom多100
userDao.addMoney();
}
4、如何解决上边的问题?
使用事务进行解决
事务操作的过程
二、spring事务
1、事务添加到JavaEE三层架构里面的Service层(业务逻辑层)
2、spring中有两种事务管理方式
-
编程式事务管理(如上图,4步)
-
声明式事务管理(常用)
3、声明式事务管理
- 基于注解方式(常用)
- 基于xml配置文件方式
4、在spring进行声明式事务管理,底层使用AOP
5、spring事务管理API
(1)提供一个接口,代表事务管理器,这个接口针对不同的框架提供不同的实现类
三、事务操作(注解实现声明式事务管理)
3.1、在spring配置文件中配置事务管理器
<!--创建事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入数据源。ref后跟的式数据源-->
<property name="dataSource" ref="dataSource"></property>
</bean>
3.2、在spring配置文件中开启事务注解
- 在spring配置文件中引入名称空间tx
- 开启事务注解
<!--开启事务注解-->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
3.3、在service类上面(或者service类里面方法上)添加事务注解
-
@Transactional,这个注解可以添加类上面,也可以添加方法上面。
-
添加到类上面,这个类里面所有方法都添加事务。
-
添加到方法上面,只是为这个方法添加事务。
四、声明式事务管理参数配置
在service类上面添加注解@Transactional,在这个注解里面可以配置事务相关参数。
4.1、propagation:事务传播行为
使用方法:就是在Transactional注解后边的括号内添加propagation = xxx
例如: @Transactional(propagation = Propagation.REQUIRED)
事务传播行为一般是:多事务方法之间的调用,这个过程中事务时如何进行管理的
图片来自尚硅谷王泽老师B站视频
事务的传播行为指方法之间事务的传播,比如方法A调用了方法B:
有7种,required 、required_new常用:
- REQUIRED
Spring默认的传播机制,如果A有事务就使用当前事务, 如果A没有事务, 就创建一个新事务。 - REQUIRES_NEW
不管A有没有事务都创建一个新事务。 - NEVER
如果A有事务就抛异常, 如果A没有事务, 就以非事务执行。
4.2、ioslation:事务隔离级别
使用方法:就是在Transactional注解后边的括号内添加,如下。如果有多种,逗号隔开。
@Transactional(isolation = Isolation.REPEATABLE_READ)
并发下事务会产生的问题
举个例子,事务A和事务B操纵的是同一个资源,事务A有若干个子事务,事务B也有若干个子事务,事务A和事务B在高并发的情况下,会出现各种各样的问题。
脏读、不可重复读、幻读
(1)脏读(Dirty read)
脏读发生在一个事务读取了被另一个事务改写但尚未提交的数据时。
(2)不可重复读(Nonrepeatable read)
不可重复读发生在一个事务执行相同的查询两次或两次以上,但每次查询结果都不相同时。这通常是由于另一个并发事务在两次查询之间更新了数据。
(不可重复读重点在修改)
(3)幻读(Phantom reads)
幻读和不可重复读相似。当一个事务(T1)读取几行记录后,另一个并发事务(T2)插入或者删除了一些记录时,幻读就发生了。在后来的查询中,第一个事务(T1)就会发现一些原来没有或少了的额外记录。
(幻读重点在新增或删除)
参考的blog:https://www.cnblogs.com/mseddl/p/11577846.html
解决:通过设置事务隔离级别,解决读的问题
隔离级别 | 含义 |
---|---|
Read Uncommitted | 读未提交:可能导致脏读、幻读或不可重复读。 |
Read Committed | 读已提交:可防止脏读,但幻读和不可重复读仍可能发生。 |
Repeated Read | 可重复读:可防止脏读和不可重复读,但幻读仍可能发生。 |
Serializable | 串行化:完全服从ACID的隔离级别,确保不发生脏读、不可重复读和幻影读。 |
4.3、timeout:超时时间
- 事务需要在一定时间内进行提交,如果不提交,进行回滚
- 默认值是-1,设置时间以秒单位进行计算
- 设置格式:
@Transactional(timeout = -1)
4.4、readOnly:是否只读
- readOnly默认值是false,表示可以查询,可以添加、修改和删除操作
- 可以设置readOnly值是true,设置之后,只能查询
- 设置格式:
@Transactional(readOnly = false)
4.5、rollbackFor:回滚
- @Transactional的rollbackFor用于指定能够触发事务回滚的异常类型,可以指定多个,用逗号分隔。
- rollbackFor默认值为UncheckedException,包括了RuntimeException和Error.
- 当我们直接使用@Transactional不指定rollbackFor时,Exception及其子类都不会触发回滚。
- 设置格式:
@Transactional(rollbackOn = Exception.class)
4.6、noRollbackFor:不回滚
- 设置出现哪些异常不进行事务回滚
练习代码:
链接:https://pan.baidu.com/s/1jOYuR-sfeT6DFhLWXqJOpg
提取码:vx8x
最后
以上就是帅气豆芽为你收集整理的spring事务入门级理解的全部内容,希望文章能够帮你解决spring事务入门级理解所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复