声明式事务(XML)

使用spring提供的专用于mybatis的事务管理器在xml中声明式事务

声明式事务需要使用到的标签

tx配置

进行<tx 标签的使用需要在xml头部导入命名空间

xmlns:tx="http://www.springframework.org/schema/tx"
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd

声明式事务需要用到的事务管理器类

<!--    将事务管理器交给ioc管理--><bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><!--    从ioc中获取DataSource--><property name="dataSource" ref="dataSource"/></bean>

< tx:advice> 标签

⚫ 名称:tx:advice
⚫ 类型:标签
⚫ 归属:beans标签
⚫ 作用:专用于声明事务通知
⚫ 格式:

<beans><tx:advice id="txAdvice" transaction-manager="txManager"></tx:advice>
</beans>

⚫ 基本属性:
◆ id :用于配置aop时指定通知器的id
◆ transaction-manager :指定事务管理器bean

< tx:attributes> 标签

⚫ 名称:tx:attributes
⚫ 类型:标签
⚫ 归属:tx:advice标签
⚫ 作用:定义通知属性
⚫ 格式:

<tx:advice id="txAdvice" transaction-manager="txManager"><tx:attributes></tx:attributes>
</tx:advice>

⚫ 基本属性:
◆ 无

< tx:method>标签

名称:tx:method
⚫ 类型:标签
⚫ 归属:tx:attribute标签
⚫ 作用:设置具体的事务属性
⚫ 格式:

<tx:attributes><tx:method name="*" read-only="false" /><tx:method name="get*" read-only="true" />
</tx:attributes>

⚫ 说明:
通常事务属性会配置多个,包含1个读写的全事务属性,1个只读的查询类事务属性

tx:method属性 争对方法配置不同方法的事务信息
<!--             <tx:method/>可以配置多个<tx:methodname="*"                待添加事务的方法名表达式(支持*号通配符),例如get* 、* 、……read-only="false"       设置事务的读写属性,true为只读,false为读写timeout="-1"            设置事务超时时长,单位秒isolation="DEFAULT"     设置事务隔离级别,该隔离级设定是基于Spring的设定,非数据库端no-rollback-for=""      设置事务中不回滚的异常,多个异常间使用,分割rollback-for=""         设置事务中必回滚的异常,多个异常间使用,分割propagation="REQUIRED"  设置事务的传播行为/>
-->

模板

⚫ 使用tx命名空间配置事务专属通知类

<tx:advice id="txAdvice" transaction-manager="txManager"><tx:attributes><tx:method name="*" read-only="false" /><tx:method name="find*" read-only="true" /></tx:attributes>
</tx:advice>

⚫ 使用aop:advisor在AOP配置中引用事务专属通知类

<aop:config><aop:pointcut id="pt" expression="execution(* *..*(..))"/><aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/>
</aop:config>

转账案列进行事务管理(xml声明式事务)

mysql数据表

下面的案列就是对这两个数据进行更新的事务管理

搭建一个maven项目

pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.fs</groupId><artifactId>day04_spring_AOP_Transaction_01</artifactId><version>1.0-SNAPSHOT</version><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.1.9.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.1.9.RELEASE</version></dependency><!--        jdbc--><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.1.9.RELEASE</version></dependency><!--        spring整合mybatis--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>2.0.1</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.5</version></dependency><!--        mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency><!--druid连接池--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.20</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version></dependency><!--        aop切面包--><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.5</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency></dependencies></project>

配置文件(主配置文件中有详细的注释解释)

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"xmlns:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><!--    扫描spring的注解--><context:component-scan base-package="com.fs"/>
<!--    读取类路径下的.properties文件--><context:property-placeholder location="classpath:jdbc.properties"/><!--    配置链接池--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean>
<!--    配置MyBatis-->
<!--    配置SqlSession的会话工厂--><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"/></bean>
<!--    配置MyBatis动态代理映射对象--><bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.fs.dao"/></bean><!--    声明式事务(XML)-->
<!--    将事务管理器交给ioc管理--><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/></bean><!--    定义事务管理的通知类 ,配置不同方法的事务信息命名空间xmlns:tx="http://www.springframework.org/schema/tx"--><tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes>
<!--             <tx:method/>可以配置多个<tx:methodname="*"                待添加事务的方法名表达式(支持*号通配符),例如get* 、* 、……read-only="false"       设置事务的读写属性,true为只读,false为读写timeout="-1"            设置事务超时时长,单位秒isolation="DEFAULT"     设置事务隔离级别,该隔离级设定是基于Spring的设定,非数据库端no-rollback-for=""      设置事务中不回滚的异常,多个异常间使用,分割rollback-for=""         设置事务中必回滚的异常,多个异常间使用,分割propagation="REQUIRED"  设置事务的传播行为/>
-->
<!--   *代表所有方法   该事务是只读的吗? false不是      --><tx:method name="*" read-only="false"/>
<!--     find*  代表find开头的所有方法只读       --><tx:method name="find*" read-only="true"/></tx:attributes></tx:advice><!--    配置aop--><aop:config>
<!--        配置切入点 注意切入点表达式是否正确--><aop:pointcut id="pt" expression="execution(* com.fs.service.impl.*.*(..))"/>
<!--        使用aop:advisor在AOP配置中引用事务专属通知类--><aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/></aop:config>
</beans>
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://192.168.93.132:3306/test
jdbc.username=root
jdbc.password=root

pojo 实体类

Account
package com.fs.pojo;import lombok.Data;@Data
public class Account {private Integer id;private String name;private Double money;
}

dao

AccountDao
package com.fs.dao;import com.fs.pojo.Account;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;import java.util.List;public interface AccountDao {@Select("select * from account")List<Account> findAll();//查询所有//根据名字修改money@Update("UPDATE account SET money = #{money} WHERE name = #{name}")void transferMoney(Account account);//根据名字查询账户信息@Select("select * from account where name = #{name}")Account findAccountByName(@Param("name") String name);
}

service

AccountService
package com.fs.service;import com.fs.pojo.Account;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;import java.util.List;public interface AccountService {List<Account> findAll();Account findAccountByName(String name);void transferMoneyAtoB(String aName,String bName,Integer money);
}

impl.AccountServiceImpl 代码中有spring事务管理器在业务层硬编码进行事务管理的代码(注释了)

在业务类中,我也使用编码的方式对spring的业务层进行了事务控制(注释代码就是)

package com.fs.service.impl;import com.fs.dao.AccountDao;
import com.fs.pojo.Account;
import com.fs.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;import javax.sql.DataSource;
import java.util.List;/*<!--  把业务类 AccountServiceImpl 交给ioc管理 --><bean id="accountServiceImpl" class="com.fs.service.impl.AccountServiceImpl">
<!--       依耐注入dao,这个dao被MyBatis动态代理实现后被spring存放在ioc容器中--><property name="accountDao" ref="accountDao"/></bean>*/
@Service
public class AccountServiceImpl implements AccountService {//从ioc获取MyBatis动态代理的accountDao实现类@Autowiredprivate AccountDao accountDao;@Autowiredprivate DataSource dataSource;@Overridepublic List<Account> findAll() {return accountDao.findAll();}@Overridepublic Account findAccountByName(String name) {return null;}/*⚫ 使用spring提供的专用于mybatis的事务管理器在业务层硬编码进行事务管理⚫ 业务层要注入dataSource对象//转账的业务实现@Overridepublic void transferMoneyAtoB(String aName, String bName, Integer money) {//先查出两个人的数据Account aAccount = accountDao.findAccountByName(aName);Account bAccount = accountDao.findAccountByName(bName);//然后a减钱,b加钱aAccount.setMoney(aAccount.getMoney()-money);bAccount.setMoney(bAccount.getMoney()+money);//编程调用事务//开启事务,使用Spring的平台事务管理器,是一个接口,使用他的实现类构造器传递一个连接池PlatformTransactionManager ptm = new DataSourceTransactionManager(dataSource);//创建事务定义对象TransactionDefinition td = new DefaultTransactionDefinition();//创建事务状态对象,用于控制事务执行TransactionStatus ts = ptm.getTransaction(td);//然后调用转账方法(sql语句为更新账户)accountDao.transferMoney(aAccount);//制作一个异常int i = 1/0;accountDao.transferMoney(bAccount);//提交事务ptm.commit(ts);}*///转账的业务实现@Overridepublic void transferMoneyAtoB(String aName, String bName, Integer money) {//先查出两个人的数据Account aAccount = accountDao.findAccountByName(aName);Account bAccount = accountDao.findAccountByName(bName);//然后a减钱,b加钱aAccount.setMoney(aAccount.getMoney()-money);bAccount.setMoney(bAccount.getMoney()+money);//然后调用转账方法(sql语句为更新账户)accountDao.transferMoney(aAccount);//制作一个异常//int i = 1/0;accountDao.transferMoney(bAccount);}
}

测试代码

package com.fs.service.impl;import com.fs.config.SpringConfig;
import com.fs.pojo.Account;
import com.fs.service.AccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import java.util.List;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class AccountServiceImplTestXML {@Autowiredprivate AccountService accountService;//测试查询所有方法@Testpublic void findAll() {List<Account> all = accountService.findAll();System.out.println(all);}//测试转账方法@Testpublic void transferMoneyAtoB() {//测试转账方法accountService.transferMoneyAtoB("小付","小花",100);}}

transferMoneyAtoB()方法测试运行后数据库中结果

业务层转账方法正常运行成功后数据表数据

由于我们测试代码中是小付向小花转账100元,代码执行成功后应该小付900,小花1100

业务层转账方法我们给制作一个异常1/0 的/ by zero异常,
运存测试转账方法控制台输出

数据库中表的数据
小付原本900,小花1100,我们进行了转账业务,但是制作了异常,事务会进行回滚,所以金额不会发生变化

事务传播行为

Spring中的7个事务传播行为:

spring控制事务:声明式事务(XML)事务的传播行为相关推荐

  1. Spring的编程式事务声明式事务 基于注解的声明式事务控制

    文章目录 Spring中编程式事务 基于XML的声明式事务控制 基于注解的声明式事务控制 Spring集成web环境 Spring中编程式事务 Spring的事务控制可以分为编程式事务控制和声明式事务 ...

  2. Spring源码——声明式事务流程

    前言 最近回顾了一下Spring源码,准备用思维导图的方式简单的将整个源码内容的流程展示出来,思维导图.图片等文件更新在https://github.com/MrSorrow/spring-frame ...

  3. spring控制事务:声明式事务(注解)

    声明式事务(注解) spring声明事务的方式,使用注解的方式 @Transactional ⚫ 名称:@Transactional ⚫ 类型:方法注解,类注解,接口注解 ⚫ 位置:方法定义上方,类定 ...

  4. spring+mybatis之声明式事务管理初识(小实例)

    前几篇的文章都只是初步学习spring和mybatis框架,所写的实例也都非常简单,所进行的数据访问控制也都很简单,没有加入事务管理.这篇文章将初步接触事务管理. 1.事务管理 理解事务管理之前,先通 ...

  5. spring 注解开启声明式事务

    spring开启声明式事务: 导入依赖: pom.xml <dependencies><!-- https://mvnrepository.com/artifact/org.spri ...

  6. Spring Boot中声明式数据库事务使用与理解

    JDBC的数据库事务 传统JDBC的数据库事务的一个示例如下代码所示,该示例仅为一个insertUser方法的数据库事务过程.可以看到,如果还存在很多其他的数据库事务需要,则需要编写很多类似于如下的代 ...

  7. 8.Spring整合Hibernate_2_声明式的事务管理(Annotation的方式)

    声明式的事务管理(AOP的主要用途之一) (Annotation的方式) 1.加入annotation.xsd 2.加入txManager bean 3.<tx:annotation-drive ...

  8. Spring AOP实现声明式事务代码分析

    众所周知,Spring的声明式事务是利用AOP手段实现的,所谓"深入一点,你会更快乐",本文试图给出相关代码分析. AOP联盟为增强定义了org.aopalliance.aop.A ...

  9. JDBC事务和JTA事务的区别 --包含spring事务 声明式事务

    2019独角兽企业重金招聘Python工程师标准>>> 一.事务概述 事务表示一个由一系列的数据库操作组成的不可分割的逻辑单位,其中的操作要么全做要么全都不做. 与事务相关的操作主要 ...

最新文章

  1. 【快乐水题】2000. 反转单词前缀
  2. oppoJava面试题,腾讯社招三面多久联系
  3. ignite通过注解配置查询
  4. linux下配置iscsi存储,linux 下iscsi网络存储配置
  5. 【clickhouse】flink jdbc 方式写入 clickhouse 报错 request to {}->http://xxx:8123: Broken pipe
  6. 以编程方式在ASP.NET MVC中使用多个HTML Select控件
  7. 守护进程之PHP实现
  8. 至2015新的一年!
  9. hibernate mysql语句_打印hibernate的SQL语句的几种办法
  10. 生物计算机的发展和应用,计算机的发展及其在生物医学中的应用
  11. python java 速度_Java Go python 运行速度对比
  12. 蓝牙核心规范(V5.2)7.8-深入详解之SMP(安全管理协议)|LE配对过程(1)
  13. Eclipse中SVN分支与合并
  14. 思科模拟器的简单安装和使用
  15. 吉比特H2-3光猫破解超级密码
  16. 敏捷测试的关键成功要素
  17. 面试利器,精心整理了份Python数据分析,知识点高清速查表!
  18. 文件夹删除了如何恢复?轻松恢复教学
  19. ITILv4 MP认证以及证书展示
  20. Dual Band Wireless-AC 3165无线驱动无法开启wifi

热门文章

  1. Repeater 绑定下拉列表
  2. for循环与内置方法详解
  3. iToken----开发前准备
  4. 初学视觉学习笔记----用摄像头获取图片
  5. 这样才能使本地Mysql服务允许被外部主机连接(两步)
  6. input和img图片水平对齐
  7. [评论]为什么中国的程序员技术偏低
  8. FCKeditor图片上传 进度条不动
  9. npm打包前端项目太慢问题分析以及暂时解决方案
  10. CENTOS7配置静态IP后无法ping通外部网络的问题