一、事务介绍

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

(2)为什么要使用事务--银行转账举例说明

(1) lucy 转账100元给mary

(2)lucy少100,mary多100

假如(1)已执行且出现异常,(2)还未执行,如果不使用事务,则会出现lucy的100元不见的问题

(3)where(在哪里使用)--事务可以作用于conroller层、service层、dao层,不过一般是放在sevice层

@Transactional可以用在类,也可以用在方法上:

用在方法上,表示该方法使用事务;

用在类上,表示类中的所有方法使用事务

(4)how(spring事务底层实现原理是什么)-->AOP

(5)how(spring如何实现事务)

          Spring提供一个接口,代表事务管理器,这个接口针对不同的框架提供不同的实现类

spring事件应用场景 spring事务应用场景_Source

(6)数据库提供的事务四个特性(ACID)

  1. 原子性:要么都成功,要么都失败,是一个原子。
  2. 一致性:事务是要求强一致性的。
  3. 隔离性:多事务之间操作同一数据(即并发操作同一数据),相互隔离互不影响。如果不考虑隔离性,会产生脏读、不可重复读、虚(幻)读这三个读问题。
  4. 持久性:事务提交以后,会持久化存在数据库中

ACID仅是数据库提供的事务特性,spring对事务属性进行了扩展,如增加了事务传播属性。传播属性是描述:同一线程中,事务嵌套时,事务如何管理

(7)spring事务需要的依赖jar(maven项目)

<!-- JdbcTemplate实现jar -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>${spring.version}</version>
</dependency>

<!-- 数据库驱动 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.43</version>
</dependency>

<!-- 数据库连接池 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.12</version>
</dependency>
<!-- 事务管理 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>${spring.version}</version>
</dependency>

二、环境搭建--纯注解方式

(1)配置类

package com.fuping3.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;

@Configuration //配置类
@ComponentScan(basePackages = {"com.fuping3"})  //组件扫描
@EnableTransactionManagement //开启事务
public class DaoConfig {
    /**
     * 创建带连接池的数据源
     * @return
     * @throws Exception
     */
    @Bean
    public DataSource dataSource() throws Exception {
        DruidDataSource dataSource=new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/fuping3?useSSL=false");
        dataSource.setUsername("root");
        dataSource.setPassword("123456");
        return dataSource;
    }

    /**
     * 创建JdbcTemplate对象
     * @param dataSource
     * @return
     */
    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource){
        return new JdbcTemplate(dataSource);
    }

    /**
     * 创建事务管理器
     * @param dataSource
     * @return
     */
    @Bean
    public DataSourceTransactionManager transactionManager(DataSource dataSource){
        return new DataSourceTransactionManager(dataSource);
    }
}

(2)service代码

@Service
@Transactional
public class BookService {
    .
    .
    .
}

@Service
public class BookService {
    .
    .
    .
    
    @Transactional
    public int addBook(Book book){
        System.out.println("添加业务逻辑处理。。。");
        int add= bookDao.addBook(book);
        return add;
    }
}

三、环境搭建--注解方式

(1)spring配置文件

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xmlns:tx="http://www.springframework.org/schema/tx"
       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/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">

    <!--创建数据源(带druid连接池)-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/fuping3?useSSL=false"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </bean>

    <!--创建JdbcTemplate对象,给DAO层使用-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--注入数据源-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

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

    <!--开启注解式事务-->
    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

</beans>

(2)service层代码

          同环境搭建--纯注解方式

四、环境搭建--xml方式

(1)spring配置文件核心代码

<!--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="accountMoney" propagation="REQUIRED"/>
        <!--<tx:method name="account*"/>-->
    </tx:attributes>
</tx:advice>

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