Java spring - 事务管理

一、什么是事务

(本颜色字体为引导,帮助读者更易分辨重点和简单点)

(1)事务就是数据库操作最基本单元,逻辑上一组操作,要么都成功,如果有一个失败所有操作都失败。

(2)典型场景:银行转账


二、事务的四大特性(ACID)

概念性的东西稍微了解即可

(1)原子性

        不可分割,要么成功,要失败都失败。

(2)一致性

        转账之前,转账之后两个人总的钱是一样的

(3)隔离性

        两个人操作同一条记录不会产生影响

(4)持久性

        提交之后,表中数据发生变化


三、事务操作(搭建事务操作环境)

前期准备,需认真看。本部分通过模拟一个转账环境,帮助读者了解事务操作。

在一个转账环境之下,我们会有三层结构

(1)WEB层:用户可视化操作层

(2)Service层:书写业务逻辑

(3)Dao层:编写数据库的操作

模块模拟图 

下面是具体操作

1、创建bank数据库表,添加记录

2、创建service,搭建dao,完成对象和关系的注入

(1)配置依赖,service注入dao,在dao中注入JdbcTemplate,在JdbcTemplate注入DataSource

pom.xml 

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>

Dao类: 

package thing;

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

@Repository
public class UserDaoImpl implements UserDao{
    @Autowired
    private JdbcTemplate jdbcTemplate;
    
}

Service类

package thing;

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

@Service
public class UserService {
    //注入Dao
    @Autowired
    private UserDao userDao;

}

注入JdbcTemplate: 

<?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:util="http://www.springframework.org/schema/util"
       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/context  http://www.springframework.org/schema/context/spring-context.xsd
">


        <!--引入外部文件-->
        <context:property-placeholder location="classpath:jdbc.properties"/>

        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql:///bank"/>
            <property name="username" value="root"/>
            <property name="password" value="wuguixin"/>
        </bean>
        <!--注入jdbc模版-->
        <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
        <!--扫描包-->
        <context:component-scan base-package="thing"></context:component-scan>


</beans>

 (2)在Dao中创建两个方法,一个多钱的方法,一个少钱的方法(先在Dao接口中设计相关方法,再在实现类中重写方法)

(3)在Service类中执行相关操作

(4)执行测试

 (5)测试结果

  


四、事务操作(Spring事务管理)

概念性的东西稍微了解即可

1、事务一般添加到JavaEE的三层结构的Service层中

2、在Spring中进行事务管理操作

(1)有两种方式:编程式事务管理和声明式事务管理(一般都使用声明式)

3、声明式事务管理

(1)基于注解方式(更加简单方便)

(2)基于xml方式(基本不用)

本文不讲xml方式实现,因为开发效率较低

4、在Spring进行声明式事务管理,底层使用AOP原理

5、Spring事务管理API

(1)在.class文件中输入

import org.springframework.transaction.*;

(2)control+H对准PlatformTransactionManager查找继承结构

 Spring做任务管理是通过接口做到的,针对不同的框架有不同的接口

笔者用的是durid数据库连接池,整合了jdbc框架,所以用的是DataSourceTransactionManager

如果整合的是Hibernate框架用的则是HibernateTransactionManager接口


五、事务操作(注解声明式事务管理)

事物操作的流程,认真看

1、在spring配置文件中配置事务管理器

<!--        创建事务管理器-->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--            注入数据源-->
            <property name="dataSource" ref="dataSource"></property>
        </bean>

2、在spring配置文件,开启事务注解

(1) 在spring配置文件中引入名称空间tx

<?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:aop="http://www.springframework.org/schema/aop"
       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/context
                           http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/tx
                           http://www.springframework.org/schema/tx/spring-tx.xsd
                           http://www.springframework.org/schema/aop
                           http://www.springframework.org/schema/aop/spring-aop.xsd">

(2)开启事务注释

<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

3、在service类上面(获得service类里面方法上面)添加事务注解

- @Transactional, 这个注解可以添加到类上面,也可以添加到方法上面

- 放到类上就等于所有方法添加注解

package thing;

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

@Service
@Transactional
public class UserService {
    //注入Dao
    @Autowired
    private UserDao userDao;
    public void operation(){
        userDao.addMoney();
        userDao.reduceMoney();
    }
}

4、测试

(1)测试代码

    @Test
    public void test1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("thing.xml");
        UserService userService = applicationContext.getBean("userService",UserService.class);
        userService.operation();
    }

(3)测试分析 

测试分析:当我们在这个类中注解@Transactional,如果发生了异常,事务就会回滚。所以operation执行步骤会是

addMoney() -> 10/0(发生Exception) -> 事务回滚 = operation()方法没执行


六、事务操作(声明式事务管理参数配置)

事物操作的参数,需要掌握

1、propagation:事务的传播行为

当一个事务方法被另一个事物方法调用的时候,那么这个事物如何进行

Required就是新插队旧事物

Required_NEW就是必须执行新事物,挂起旧事物

Support就是变成串行了,新事物的方法直接加入旧事物中,变成一个事物。 

2、isolation:隔离等级

为了解决并发操作出现的问题,多事物操作之间不会产生影响。

如不采用隔离,可能出现:

脏读:读到未提交数据(因为事物有可能回滚)

不可重复读:第一次读和第二次读的数据不一样(因为另一个事物修改了数据)

虚读:当未提交数据也读到了另一事物修改的数据导致两次读数据不一样

 设置隔离级别

注:MySQL默认设置的是RepeatableRead

3、timout:

超时时间

(1)事物在一定时间内一定要提交,不然就事物回滚

(2)默认是-1,代表不超时

(3)设置时间以秒单位计算

3、readOnly: 

是否读

(1)读:查询操作。 写:添加删除操作

(2)readOnly默认值false

(3)设置为true之后就只可以查询了

4、rollbackFor:回滚

设置出现了哪些异常进行事务回滚

5、noRollbackFor:

设置出现了哪些异常不会进行事务回滚


恭喜你!Java-spring事务就完结啦

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值