Java框架--spring(四、事务管理、事务传播、spring整合mybatis)

事务管理

事务:看作一次对数据的若干操作组成的一个序列,是一个整体的过程,要么成功要么都不成功(转账)
JdbcTemplate默认使用jdbc的事务,提交事务,自动的(执行完自动提交)
spirng中提供了事务管理

编程式事务

注入TransactionTemplate事务管理对象,在提交事务or回滚事务时,用代码实现

声明式事务

声明式事务是基于AOP实现的,本质是对方法前后进行拦截

有xml和注解两种实现方式
配置事务管理器

<!-- 配置 spring 事务管理类, 并注入数据源 --> 
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
	<property name="dataSource" ref="dataSource"></property> 
</bean>

基于xml实现

<tx:advice id="txadvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="save*" propagation="REQUIRED"/>
    </tx:attributes>
</tx:advice>
 
<aop:config>
	<aop:pointcut expression="execution(* com.ff.spring.service.UserService.*(..))" id="allmethod"/>
    <aop:advisor advice-ref="txadvice" pointcut-ref="allmethod"/>
</aop:config>

基于注解实现

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

在service层控制事务

@Service(value="userservice") 
@Transactional(propagation=Propagation.REQUIRED)

事务传播

一个事务方法被另一个事务方法调用时,该方法如何执行

7种传播行为

事务传播行为说明
PROPAGATION_REQUIRED如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。
PROPAGATION_SUPPORTS支持当前事务,如果当前没有事务,就以非事务方式执行
PROPAGATION_MANDATORY使用当前的事务,如果当前没有事务,就抛出异常
PROPAGATION_REQUIRES_NE W新建事务,如果当前存在事务,把当前事务挂起
PROPAGATION_NOT_SUPPOR TED以非事务方式执行操作,如果当前存在事务,就把当前事务 挂起
PROPAGATION_NEVER以非事务方式执行,如果当前存在事务,则抛出异常
PROPAGATION_NESTED如果当前存在事务,则在嵌套事务内执行。如果当前没有事 务,则执行与 PROPAGATION_REQUIRED 类似的操作

重点了解这三个

  1. PROPAGATION_REQUIRED:
    指定的方法必须在事务内执行
    当前存在事务就加入到事务中,没有事务新建一个事务
    是spring的默认传播行为

  2. PROPAGATION_SUPPORTS:
    支持当前事务,若当前没有事务,就以非事务方式执行

  3. PROPAGATION_REQUIRES_NEW:
    总是新建一个事务,若当前存在事务,将当前事务挂起,直到新建事务结束

声明式事务不生效的场景

  • @Transactional 应用在非 public 修饰的方法上
  • @Transactional 注解属性 propagation 设置错误
  • 同一个类中方法调用,导致@Transactional 失效
  • 异常被 catch 捕获导致@Transactional 失效
  • 数据库引擎不支持事务(MySQL中InnoDB是支持事务的)

spring整合mybatis

集成mybaits的原理就是将SqlSessionFactory交给spring来管理,由spring管理对dao接口的代理实现

1. 导入 jar 包

mybatis

<!--mybatis-->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.2</version>
</dependency>

mybatis-spring整合包

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.1</version>
</dependency>

mysql-connector-java 数据库驱动

<!-- mysql-connector-java -->
<dependency>
     <groupId>mysql</groupId>
     <artifactId>mysql-connector-java</artifactId>
     <version>8.0.16</version>
</dependency>

spring相关jar包

<!--spring.context-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.2.RELEASE</version>
</dependency>

<!-- spring-jdbc-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.2.RELEASE</version>
</dependency>

<!-- spring-aop -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.2.2.RELEASE</version>
</dependency>

<!-- 阿里数据源 -->
<dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>druid</artifactId>
     <version>1.1.10</version>
</dependency>

2. 配置spirng.xml文件

<!--开启spring注解扫描
base-package:指定包下所有类是否有注解标签-->
<context:component-scan base-package="com.ffyc.ssm"></context:component-scan>

<import resource="db.xml"></import>
<import resource="spring_mybatis.xml"></import>
<import resource="spring_mvc.xml"></import>

3. 配置spring_mybaits.xml

配置 sqlSessionFactory,指定生成接口代理

<!--1.spring管理生成SqlSessionFactory,读取mybatis的各项配置-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="druidDataSource"></property>
    <property name="configLocation" value="classpath:mybatis.xml"></property>
    <property name="mapperLocations" value="classpath:mapper/*.xml"></property>
</bean>

<!--2.生成指定包下面的接口代理对象-->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.xx.xx.dao"></property>
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>

4. 配置mybaits.xml

<!--配置-->
<configuration>

    <settings>
        <!-- 配置日志实现, 使用log4j,添加log4j -->
        <setting name="logImpl" value="LOG4J"/>
        <!--开启驼峰映射  设置启用数据库字段下划线映射到java对象的驼峰式命名属性,默认为false-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <!-- 开启懒加载
        <setting name="lazyLoadingEnabled" value="true"/>-->
        <!--lazyLoadTriggerMethods:指定哪些方法触发延迟加载-->
        <setting name="lazyLoadTriggerMethods" value=""/>
        <!--开启二级缓存-->
        <setting name="cacheEnabled" value="true"/>
    </settings>

    <typeAliases>
        <package name="com.xx.xx.model"/>
    </typeAliases>


</configuration>

5.配置数据库连接db.xml

<!--配置与数据库连接相关配置-->

    <!--1.spring读入属性文件-->
    <context:property-placeholder location="classpath:config.properties"></context:property-placeholder>

    <!--2.配置druid数据库连接对象-->
    <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="username" value="${uname}"></property>
        <property name="password" value="${pwd}"></property>
        <property name="url" value="${url}"></property>
        <property name="driverClassName" value="${driver}"></property>
        <property name="initialSize" value="${initialSize}"></property>
        <property name="maxActive" value="${maxActive}"></property>
    </bean>

    <!-- 3.声明式事务 配置spring事务管理类-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="druidDataSource"></property>
    </bean>

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

6. 配置config.properties文件

# jdbc驱动
driver=com.mysql.cj.jdbc.Driver
# 连接数据库地址
url=jdbc:mysql://127.0.0.1:3306/ssm?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
# 数据库用户名,用于连接数据库
uname=root
# 用户密码(用于连接数据库)
pwd=lanlei6843
#连接池初始化时初始化的数据库连接数
initialSize=10
#连接池支持的最大连接数
maxActive=20

7. 配置日志文件log4j.properties

log4j.rootLogger=debug,stdout,D
#System out Console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%p] %d{yyyy-MM-dd HH:mm:ss,SSS} %m%n
#System out File
log4j.appender.D=org.apache.log4j.FileAppender
log4j.appender.D=org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File=E://logs/log.log
log4j.appender.D.Append=true
log4j.appender.D.layout=org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ] -[%l] %m%n
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值