Spring 学习笔记之事务管理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SIMBA1949/article/details/82313259

Spring 学习笔记之事务管理

Module 介绍

Spring-Transaction-Annotaion:以注解方式配置的声明式事务

Spring-Transaction-XML:以XML方式配置的声明式事务

Spring 事务控制

事务控制分类

  • 编程式事务(略)

  • 声明式事务

    • 以XML方式配置的声明式事务
    • 以注解方式配置的声明式事务

以XML方式配置的声明式事务

pom.xml需要引入:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

Springboot 引入 事务控制配置文件(applicationContext-db.xml)

ApplicationContextConfig.java

package top.simba1949;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author [email protected]
 * @date 2018/8/25 8:01
 */
@SpringBootApplication
@MapperScan(basePackages = "top.simba1949.mapper")
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class,args);
    }
}

applicationContext.xml 和 applicationContext-db.xml融合到一个spring容器中

applicationContext.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"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <import resource="applicationContext-db.xml"></import>
</beans>

applicationContext-db.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: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/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:property-placeholder location="jdbc.properties"/>

    <aop:config>
        <aop:pointcut id="aopPoincut" expression="execution(* top.simba1949.service.impl.*.*(..))"></aop:pointcut>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="aopPoincut"></aop:advisor>
    </aop:config>
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!--tx:method表示哪些方法需要开启事务,propagation表示必须要求,
                isolation表示事物隔离级别,rollback-for表示发生异常回滚
            -->
            <tx:method name="add*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="java.lang.Exception"/>
            <tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="java.lang.Exception"/>
            <tx:method name="insert*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="java.lang.Exception"/>
            <tx:method name="update*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="java.lang.Exception"/>
            <tx:method name="modify*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="java.lang.Exception"/>
            <tx:method name="delete*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="java.lang.Exception"/>

            <tx:method name="query*" read-only="true"></tx:method>
            <tx:method name="select*" read-only="true"></tx:method>
            <tx:method name="find*" read-only="true"></tx:method>
        </tx:attributes>
    </tx:advice>
    <!--事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--数据源-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>

    <!--mybatis的基本配置-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--数据源配置-->
        <property name="dataSource" ref="dataSource"></property>
        <!--告诉spring,mybatis配置文件位置-->
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>
        <!--告诉spring,mybatisMpapper配置文件位置-->
        <property name="mapperLocations">
            <array>
                <value>classpath*:top/simba1949/mapper/*Mapper.xml</value>
            </array>
        </property>
        <!--给包取别名-->
        <property name="typeAliasesPackage" value="top.simba1949.common"></property>
    </bean>
    <!--mapper扫描配置-->
    <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--指定dao接口的路径-->
        <property name="basePackage" value="top.simba1949.mapper"></property>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
    </bean>
</beans>

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

</configuration>

jdbc.properties

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=19491001

以注解方式配置的声明式事务

application.properteis

server.port=8083

#mysql设置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=19491001

#表示打印出sql语句
logging.level.com.shyroke.mapper=debug

#mybatis配置
mybatis.mapper-locations=classpath*:top/simba1949/mapper/*Mapper.xml
mybatis.type-aliases-package=top.simba1949.common

Application.java

package top.simba1949;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author [email protected]
 * @date 2018/8/25 8:01
 * @MapperScan(basePackages = "top.simba1949.mapper")扫描mapper包
 */
@SpringBootApplication
@MapperScan(basePackages = "top.simba1949.mapper")
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class,args);
    }
}

CountryServiceImpl.java

@Transactional(rollbackFor = Exception.class)即可开启注解

package top.simba1949.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.simba1949.common.CountryCommon;
import top.simba1949.mapper.CountryMapper;
import top.simba1949.service.CountryService;

/**
 * @author [email protected]
 * @date 2018/8/24 23:22
 */
@Service
public class CountryServiceImpl implements CountryService {

    @Autowired
    private CountryMapper countryMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insert(CountryCommon countryCommon) {
        int i = countryMapper.insert(countryCommon);
        return i;
    }
}

@Transactional 注解详解

@Transactional(
    propagation = Propagation.REQUIRED,
    isolation = Isolation.DEFAULT,
    timeout = -1,
    readOnly = false,
    rollbackFor = Exception.class,
    noRollbackFor = Exception.class
)
属性 含义 默认值
propagation,定义事务的生命周期 REQUIRED:方法A调用式没有事务新建一个事务,当方法A调用另一个方法B时,方法B将使用相同的事务;如果方法B发生异常需要回滚的时候,整个事务数据回滚 REQUIRED
REQUIRED_NEW:方法A和方法B,在方法调用的时候无论是否有事务都开启一个新事务;这样如果方法B有异常不会导致方法A的数据回滚
NESTED:和REQUIRED_NEW类似,但是支持JDBC,不支持JPA和Hibernate
NOT_SUPPORTED:强制方法不在事务中执行,若有事务,在方法调用结束阶段事务将被挂起
NEVER:强制方法不在事务中执行,若有事务则抛出异常
MANDATORY:强制方法在事务中执行,若无事务则抛出异常
isolation:(隔离)决定了事务的完整性,处理在多事务对相同数据的处理机制 READ_UNCOMMITTED:对于在A事务里修改了一条记录但是没有提交事务,在B事务可以读取到修改后的记录。可导致脏读,可不重复读以及幻读 DEFAULT(使用当前数据库默认的级别,oracle、sql server默认为READ_COMMITTED,mysql默认REPEATABLE_READ)
READ_COMMITTED:只有当事务A里修改了一条记录且提交事务之后,B事务才可以读取到提交后的记录;阻止脏读,但是可导致不可重复读和幻读
REPEATABLE_READ:不仅能实现READ_COMMITTED的功能,而且还能阻止当A事务读取了一条记录,B事务将不允许修改这条记录;阻止了脏读,不可重复读,但是可导致幻读
SERIALIZABLE:此级别下事务是顺序执行的,可以避免上述级别的缺陷,但是开销比较大
timeout timeout事务过期时间,默认为当前数据库的事务过期时间
readonly 指定当前事务是否是只读事务 false
rollbackfor 指定哪个或者哪些异常可以引起事务回滚 Throwable的子类
noRollbackfor 指定哪个或者哪些异常不可以引起事务回滚 Throwable的子类

猜你喜欢

转载自blog.csdn.net/SIMBA1949/article/details/82313259