8. Spring-事务操作

事务操作

一、事务概念

1. 什么是事务

  1. 事务是数据库操作最基本的单元,逻辑上一组的操作,要么同时成功,要么同时失败。

2. 事务的特效(ACID)

  1. 原子性
  2. 一致性
  3. 隔离性
  4. 持久性

二、事务操作的环境搭建

1. 建表

CREATE TABLE t_account(
	id INT PRIMARY KEY AUTO_INCREMENT,
	username VARCHAR(20),
	money INT
);

INSERT INTO t_account VALUE(NULL,'lucy',100);
INSERT INTO t_account VALUE(NULL,'mary',100);

2. 目录结构

8. Spring-事务操作

3. 相关类的创建

  1. UserService类
@Service
//@Transactional(propagation = Propagation.MANDATORY,isolation = Isolation.REPEATABLE_READ,timeout = 1000)
public class UserService {

    @Autowired
    private UserDao userDao;

    //转账的方法
    public void accountMoney(){
        //try{
            //第一步 开启事务

            //第二步 进行业务操作
            userDao.add();
            //模拟异常
            //int i = 10 / 0;
            userDao.reduce();
            //第三步 无异常发生提交事务

        //}catch (Exception e){
            //第四步 出现异常回滚事务

        //}
    }

}

  1. UserDao类
public interface UserDao {

    public void add();
    public void reduce();
}
  1. UserDaoImpl类
@Repository
public class UserDaoImpl implements UserDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void add() {
        String sql = "update t_account set money = money + ? where username = ?";
        jdbcTemplate.update(sql,100,"lucy");
    }

    @Override
    public void reduce() {
        String sql = "update t_account set money = money - ? where username = ?";
        jdbcTemplate.update(sql,100,"mary");
    }
}
  1. 测试类
public class UserServiceTest extends TestCase {

    public void testAccountMoney() {
        //基于注解的测试方法
        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        UserService userService = context.getBean("userService", UserService.class);
        userService.accountMoney();
    }

    public void testAccountMoney1() {
        //基于配置文件的测试方法
        ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
        UserService userService = context.getBean("userService", UserService.class);
        userService.accountMoney();
    }
}

三、Spring事务管理介绍

  1. 事务添加到service层。
  2. 事务分为编程式事务管理和声明式事务管理,一般使用声明式事务管理。
  3. 声明式事务管理,基于注解方式和基于xml配置文件方式。
  4. 在Spring进行声明式事务管理,底层使用AOP原理。

1. 注解声明式事务管理

  1. 在spring配置文件配置事务管理器
在这里插入代码片
  1. 在spring配置文件,开启事务注解
在这里插入代码片

2. 事务参数

① propagation:事务传播行为

8. Spring-事务操作

@Transactional(propagation = Propagation.REQUIRES)

② ioslation:事务隔离级别

  1. 事务的隔离性,使得多事务之间不会产生影响。

  2. 常见的三种隔离性的问题,脏读、不可重复读、幻读。

     脏读:读取到未提交的数据。
     不可重复读:一个未提交的事务读取到另一个提交事务修改的数据。
     幻读:一个未提交的事务读取到另一个提交事务添加的数据。
     
     事务的隔离级别;	
     					脏读	  不可重复读	幻读
     read uncommitted	✓		✓		✓
     read committed				✓		✓
     repeatable read					✓
     serializable	
    
@Transactional(isolation = Isolation.REPEATABLE_READ)

③ timeout:超时时长

  1. 事务需要在一定时间内进行提交,如果不提交则回滚。
  2. 默认值-1,不设置超时时长,设置时间已秒为单位。

④ readOnly:是否只读

  1. 读-查询操作,写-增删改操作。
  2. readOnly默认值为false,可写可读。
  3. 设置为true,只能进行查询操作

⑤ rollbackFor:回滚

  1. 设置出现哪些异常进行回滚。

⑥ noRollbackFor:不回滚

  1. 设置出现哪些异常不进行回滚。

3. 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"
       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/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 http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

   <!--开启扫描-->
   <context:component-scan base-package="com.znb.spring5"></context:component-scan>



   <!--直接配置连接池-->
   <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
      <!-- 获取properties文件内容,根据key获取,使用spring表达式获取 -->
      <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
      <property name="url" value="jdbc:mysql://localhost:3306/usedb?useUnicode=true&amp;characterEncoding=utf-8&amp;useSSL=false&amp;serverTimezone=GMT"></property>
      <property name="username" value="root"></property>
      <property name="password" value="2550"></property>
   </bean>

   <!--JdbcTemplate对象-->
   <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
      <!--注入dataSourse-->
      <property name="dataSource" ref="dataSource"></property>
   </bean>

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

   <!--2.配置通知-->
   <tx:advice id="txadvice">
      <!--配置事务相关参数-->
      <tx:attributes>
         <!--指定那种规则的方法上面添加事务-->
         <tx:method name="account*" propagation="REQUIRED"/>
      </tx:attributes>
   </tx:advice>

   <!--3.配置切入点和切面-->
   <aop:config>
      <!--配置切入点-->
      <aop:pointcut id="pt" expression="execution(* com.znb.spring5.service.UserService.*(..))"/>
      <!--配置切面-->
      <aop:advisor advice-ref="txadvice" pointcut-ref="pt"></aop:advisor>
   </aop:config>

</beans>
上一篇:那些解决了我问题的URL之PHP


下一篇:SpringCloud之Eureka服务注册与发现