测试前的数据:
测试后的数据:
这样正常执行,没有问题,但是如果中途出错了呢?接着往下看。
================================================================
上面代码,如果正常执行没有问题的,但是如果代码执行过程中出现异常,就会有问题,假如在Lucy少100后代码发生了错误,那么会怎样?
我们手动添加个错误:
//转账的方法
public void accountMoney(){
// Lucy 少100
userDao.reduceMoney();
//手动添加异常
int i =100/0;
//Mary多100
userDao.addMoney();
}
这样数据的变化就会出现问题。
测试前的数据:
测试后的数据:
这样就发生了问题,Lucy少了100但是Mary却没有多。这就需要利用事务来解决,让其在发生错误的时候进行回滚。
================================================================
**1、事务添加到 JavaEE 三层结构里面 Service 层(业务逻辑层)
2、在 Spring 进行事务管理操作
有两种方式:
(1)编程式事务管理(不方便)
(2)声明式事务管理(使用)
3、声明式事务管理
(1)基于注解方式(简单方便)
(2)基于 xml 配置文件方式
4、在 Spring 进行声明式事务管理,底层使用 AOP 原理
5、Spring 事务管理 API
提供一个接口,代表事务管理器,这个接口针对不同的框架提供不同的实现类:**
Spring中使用的是DataSourceTransactionManager
===================================================================
**(1)在 spring 配置文件配置事务管理器
(2)在 spring 配置文件,开启事务注解
(3)在 spring 配置文件引入名称空间 tx
(4)开启事务注解**
bean1.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:p=“http://www.springframework.org/schema/p”
xmlns:util=“http://www.springframework.org/schema/util”
xmlns:tx=“http://www.springframework.org/schema/tx”
xmlns:context=“http://www.springframework.org/schema/context”
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package=“com.Keafmd”></context:component-scan>
<context:property-placeholder location=“classpath:jdbc.properties”/>
<tx:annotation-driven transaction-manager=“transactionManager”></tx:annotation-driven>
**在 service 类上面(或者 service 类里面方法上面)添加事务注解:
(1)@Transactional,这个注解添加到类上面,也可以添加方法上面
(2)如果把这个注解添加类上面,这个类里面所有的方法都添加事务
(3)如果把这个注解添加方法上面,为这个方法添加事务**
UserService 类:
package com.Keafmd.spring5.service;
import com.Keafmd.spring5.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
-
Keafmd
-
@ClassName: UserService
-
@Description:
-
@author: 牛哄哄的柯南
-
@date: 2021-01-20 10:08
*/
@Service
@Transactional // @Transactional,这个注解添加到类上面
public class UserService {
//注入dao
@Autowired
private UserDao userDao;
//转账的方法
public void accountMoney(){
// Lucy 少100
userDao.reduceMoney();
//手动添加异常,事务回滚
int i =100/0;
//Mary多100
userDao.addMoney();
}
}
现在我们添加事务后带着异常运行测试类:
测试前的数据:
测试后的数据:
很明显的看到测试后的数据没有变化,是因为发生了异常,进行了事务回滚,所以数据库中的数据都没有改变。
=====================================================================
在 service 类上面添加注解@Transactional,在这个注解里面可以配置事务相关参数:
事务传播行为:多事务方法直接进行调用,这个过程中事务 是如何进行管理的。
我们在add方法加了事务,update没有加,当我们的add调用update的时候,事务会怎么处理,这个过程就叫做事务的传播行为。有事务的方法调用没事务的,还有就是都有事务并且调用这些情况发生的时候事务会怎么处理,这些过程就叫做事务的传播行为。
事务的传播行为可以由传播属性指定。Spring 定义了7种类传播行为。
结合我们的例子介绍两种最常见的:
默认的是REQUIRED:
@Transactional(propagation = Propagation.REQUIRED)
相当于:@Transactional
**(1)事务有特性成为隔离性,多事务操作之间不会产生影响。不考虑隔离性产生很多问题
(2)有三个读问题:脏读、不可重复读、虚(幻)读**
脏读(致命问题):一个未提交事务读取到另一个未提交事务的数据
不可重复读(现象):一个未提交事务读取到另一提交事务修改数据
虚读(现象):一个未提交事务读取到另一提交事务添加数据
**不可重复读的重点是修改了数据,同样的条件 , 你读取过的数据 , 再次读取出来发现值不一样了。
幻读的重点是新增或者删除了数据 , 第 1 次和第 2 次读出来的记录数不一样。**
解决:通过设置事务隔离级别,解决读问题。
设置隔离级别方式:
@Transactional(isolation = Isolation.REPEATABLE_READ)
,这种可重复读是mysql默认的设置方式。
**(1)事务需要在一定时间内进行提交,如果不提交进行回滚
(2)默认值是 -1 ,设置时间以秒单位进行计算**
设置方式:@Transactional(timeout = 5)
**(1)读:查询操作,写:添加修改删除操作
(2)readOnly 默认值 false,表示可以查询,可以添加修改删除操作
(3)设置 readOnly 值是 true,设置成 true 之后,只能查询**
设置方式:@Transactional(readOnly = true)
设置出现哪些异常进行事务回滚
设置方式:@Transactional(rollbackFor=Exception.class)
设置出现哪些异常不进行事务回滚
设置方式:@Transactional(notRollbackFor=RunTimeException.class)
=========================================================================
**在 spring 配置文件中进行配置:
第一步:配置事务管理器
第二步:配置通知
第三步:配置切入点和切面**
bean2.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:p=“http://www.springframework.org/schema/p”
xmlns:aop=“http://www.springframework.org/schema/aop”
xmlns:util=“http://www.springframework.org/schema/util”
xmlns:tx=“http://www.springframework.org/schema/tx”
xmlns:context=“http://www.springframework.org/schema/context”
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package=“com.Keafmd”></context:component-scan>
<context:property-placeholder location=“classpath:jdbc.properties”/>
<tx:advice id=“txadvice”>
tx:attributes
<tx:method name=“accountMoney” propagation=“REQUIRED”/>
</tx:attributes>
</tx:advice>
aop:config
<aop:pointcut id=“pt” expression=“execution(* com.Keafmd.spring5.service.UserService.*(…))”/>
<aop:advisor advice-ref=“txadvice” pointcut-ref=“pt”/>
</aop:config>
把UserService的@Transactional注解注释掉,其它不变,新建个测试类:
package com.Keafmd.spring5.test;
import com.Keafmd.spring5.config.TxConfig;
import com.Keafmd.spring5.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
-
Keafmd
-
@ClassName: TestAccount
-
@Description:
-
@author: 牛哄哄的柯南
-
@date: 2021-01-20 10:40
*/
public class TestAccount {
@Test
public void test2(){
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
最后
无论是哪家公司,都很重视基础,大厂更加重视技术的深度和广度,面试是一个双向选择的过程,不要抱着畏惧的心态去面试,不利于自己的发挥。同时看中的应该不止薪资,还要看你是不是真的喜欢这家公司,是不是能真的得到锻炼。
针对以上面试技术点,我在这里也做一些分享,希望能更好的帮助到大家。
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
351714)]
[外链图片转存中…(img-pR52fObk-1712675351714)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-jiTlDhp7-1712675351715)]
最后
无论是哪家公司,都很重视基础,大厂更加重视技术的深度和广度,面试是一个双向选择的过程,不要抱着畏惧的心态去面试,不利于自己的发挥。同时看中的应该不止薪资,还要看你是不是真的喜欢这家公司,是不是能真的得到锻炼。
针对以上面试技术点,我在这里也做一些分享,希望能更好的帮助到大家。
[外链图片转存中…(img-kvSHsuhz-1712675351715)]
[外链图片转存中…(img-KmNDD0VR-1712675351715)]
[外链图片转存中…(img-cE1qFPIQ-1712675351716)]
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-dJ8dVkz7-1712675351716)]