刚才咱们是使用了模板操作咱们事务,当然使用模板操作比较low,还得写代码,每个方法都写太费劲了,首先把之前写的先注释掉,把这个transfer这个代码直接复制一份,然后底下展一份,留着注释掉就行了,上面的恢复原状,是这个意思不,然后事务模板的话先留着吧,然后不用他就完事了,然后接下来看一下AOP事务,AOP事务呢,咱们先讲一下原理,咱们学习了Spring中的AOP,说这个简单也简单,说起来也就这么个事,首先是通知,然后你再搞一个目标对象,然后代理,然后把这个通知织入到目标对象当中,形成一个代理对象,然后代理对象当中,这个方法,比如这个目标对象当中,方法当中,要实现一个业务逻辑,然后咱们这个通知的话,加上事务管理,然后这个变成代理对象之后,把这个事务管理业务逻辑调用,相当于动态的合在一起了,不就这点事吗,那咱们的Spring的AOP,这个Spring的AOP事务,他事其实就是这么一个事,Spring给我准备了一个事务的通知,SpringAOP,也就是他给我们准备了一个事务的通知,他已经写好了,他写好了一个事务通知,你看通知都不需要咱们写了,知道啥意思不,而这个通知我问你,假设Spring没写,要咱们自己去写,用那种类型的通知,你能想到吗,是不是环绕通知,是不是在方法之前开启,之后关闭,然后方法还得控制,用try catch包裹一下,如果出了异常,咱们是不是再回滚,其实这块的话通知,计算Spring没提供,咱们也能拿环绕通知写出来,重要是Spring写的,就不用写了,所以通知现在已经有了,目标对象咱们现在有没有,目标对象是咱们写好的service,那咱们离管理业务逻辑还差什么事,你这两条线连成代理对象要告诉他能够配置,所以这块你只需要配置就完事了,这个前面讲Spring事务配置就完事了,所以咱们接下来万事俱备,只差配置,接下来咱们来配置一下,准备工作咱们给你列一下,使用AOP来管理的话,首先你得导包,导什么包呢,4+2咱们已经有了,你要玩AOP的话,AOP的包要导进来,aspect是不是要导入进来,然后除此之外还有aop联盟,然后还有一个是咱们的织入,weaving,织入包,这是咱们昨天下午玩AOP用的包,粘贴到咱们的lib目录下,这样的话全导入进来了,还需要再做另外一件事,配置的话需要导入一个新的命名空间

导入新的约束,这个约束是tx约束,你要想配置事务通知,你得需要tx约束来配,这个事咱们已经是干了第四遍了,咱们之前导过beans,context,aop,这是第四个,tx,add在这选择spring,然后找tx

然后选择Schema Location,复制文件名粘到这里

open with xml editor,然后选design,然后beans右键

那这里的可以导入两个了,http://www.springframework.org/schema/aop这一对复制,最后这个也复制

然后再add一个,再来一个tx

这一对复制,然后最后tx

这样咱们的命名空间一共要导四个,加起来一共导4个,有一个问题不知道你们怎么想,还记得这些命名空间是干啥的,beans是咱们第一个命名空间,所以这是最基本的,这不用说,context你拿出来干啥的,注解,但是咱们现在没有注解,读取properties配置文件,配置用的,AOP咱们现在没用,所以这是配置AOP的,tx需要配置事务通知,接下来的话第三步,约束导完以后,目标对象也有了,那咱们就需要配置通知,通知的话咱们看怎么配,通知就在模板下面,在这配置事务通知,通知这个东西,是Spring已经写好了,咱们压根不用写代码,但是咱们得配一下,是叫advice吧,然后advice需要指明事务管理器,你这个transactionManager是管理事务的核心,只要是用Spring管理事务,肯定需要这玩意,是不是这个意思,这是咱们操作事务的核心,然后再到这里面,要使用tx:attributes,来指定咱们事务的属性,然后指定属性的时候,它是以方法为单位指定的,比如咱们service这个方法的话,transfer方法,所以你在配置里面指明方法是transfer,然后接下来的话你就可以配置属性,就是咱们开始的事务属性,咱们一共有三个,分别是隔离级别,隔离级别一共有几个,是不是4个,读未提交,读已提交,可以重复读,串行化,或者你不想改的话,你也可以用default默认级别,这块我就改一下,REPEATABLE_READ,还有一个属性propagation,这是咱们的传播行为,是不是REQUIRED这个,然后这里还有一个read-only,如果为true的话,现在这个只读,我这个方法显然是需要修改数据库的,所以千万别配true,就用false,看明白啥意思不,这样的话咱们事务通知就配好了,这样的话他遇到transfer方法,他就知道transfer方法呢,他就需要后面这些属性,大家配完以后,将来业务方法有好几百个,难道我要配好几百行吗,听明白啥意思吧,如果以后咱们再来一个业务方法,太痛苦了,我告诉你,在真正企业当中,他怎么配呢,看好,他们是这样配的,save*,persist*,update*,modify*,然后delete*,remove*,get*,find*,这啥意思呢,企业当中开发是这样,他直接使用通配符的方式来完成批量配置,你配置save*的意思就是说,你这个service的方法名只要以save开头,后面无论你写什么,如果你persist开头的方法,都应用后续的属性,这里就是把企业中的两套增删改查,命名都给你写上了,直接使用星号通配符,来批量为所有的service方法,来进行事务属性的定制,那这样的话反过来,以后再写service方法的时候,咱们就要按照咱们定的规则来吧,那咱们现在用transfer这个方法,那是不是要换成别的名字,按照刚才咱们配置的规则开头,明白啥意思吧,当然的话现在不打算改了,而且为了让你们看的明确一点,我会在底下再补一个,看明白啥意思不,那transfer就单独的应用下面这一个,如果其中以get或者find开头的,往往only要配成true,这样就可以防止在find或者get中间不小心操作,操作就会给你报错的,这样就是业务当中事务通知的配置,记住它是以方法为单位,进行配置了,而这个方法的话你不一定要傻乎乎的,写死一个方法名,你可以通过通配符这种方式,是不是批量来指定方法,看明白啥意思不,那通知写好之后,目标对象也有了,接下来就要配置织入,配置织入,那这个配置织入的话看着,咱们就使用AOP,然后config,这个配置方式跟昨天有点像,后面有点区别,首先要指定一个pointcut,就是指定切点,execution,然后括号方法,在这里像表达式第一次填,怎么填呢,找到transfer方法,是不是粘过来,加入星号,返回值东西,这个方法名改成*,对所有方法切入,这个类型的话改成..,任意,咱们一般是应用到所有的service当中去,这样就配完了,然后来冉鸣一个名字,叫txPc,transaction Point cut,然后再来一个aop,这个aspect是手动指定前置,咱们现在已经有现成的通知的话,就可以使用aspect,aspect就叫切面,还记得名词切面,切面是不是二合一,是通知加切入点,aop是advisor,配置切面,在Spring切面是advisor,通知的引用,advice-ref,pointcut-ref是切点的引用,这样的话你只要告诉他通知是谁呢,给这个通知起个名字,id=txAdvice,txAdvice,然后pointcut-ref是txPc,知道啥意思不,把刚才咱们的通知,应用到这个切入点,然后就完了,然后你再加入这个配置之后,他就会自动去根据你的这个切点表达式,对所有符合条件的,这个对象,织入这个通知的,而在织入通知之后,需要进一步你这个方法要使用哪个属性,来执行对应的事务,所以说白了你只要配置两行,然后配置完以后,在demo中配置一下,数据库恢复一下原状,然后接下来看到,现在转500,现在没有异常转成功了,900,1100,现在事务有没有加成功很简单,你是不是要在这造一个异常,int i = 1/0,然后再到这里执行一下,这回执行报错了,然后重点是看数据库,是不是还是900,1100,这里就是使用XML配置AOP,这个配置方式,第三步配置通知,以方法为单位,指定方法应用什么事务属性,isolation是隔离级别,propagation是隔离级别,然后read-only是否只读,这样的话事务通知就配完了,然后接下来就看第四个了,配置将通知织入目标对象,然后这个配置就是刚才看的,就这两行,切点表达式,切面再提醒一下,切面就是通知加切点,然后提供advice-ref,这里写什么东西,通知的名称,然后point-cut是切点的名称,切点通知有了以后,去加入通知了
<?xml version="1.0" encoding="UTF-8"?>
<beans  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd "><!-- 指定spring读取db.properties配置 -->
<context:property-placeholder location="classpath:db.properties"  /><!-- 事务核心管理器,封装了所有事务操作. 依赖于连接池 -->
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" ><property name="dataSource" ref="dataSource" ></property>
</bean><!-- 事务模板对象 -->
<bean name="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate" ><property name="transactionManager" ref="transactionManager" ></property>
</bean><!-- 配置事务通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager" ><tx:attributes><!-- 以方法为单位,指定方法应用什么事务属性isolation:隔离级别propagation:传播行为read-only:是否只读--><tx:method name="save*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" /><tx:method name="persist*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" /><tx:method name="update*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" /><tx:method name="modify*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" /><tx:method name="delete*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" /><tx:method name="remove*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" /><tx:method name="get*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true" /><tx:method name="find*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true" /><tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" /></tx:attributes>
</tx:advice><!-- 配置织入 -->
<aop:config  ><!-- 配置切点表达式 --><aop:pointcut expression="execution(* com.learn.service.*ServiceImpl.*(..))" id="txPc"/><!-- 配置切面 : 通知+切点advice-ref:通知的名称pointcut-ref:切点的名称--><aop:advisor advice-ref="txAdvice" pointcut-ref="txPc" />
</aop:config><!-- 1.连接池 -->
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" ><property name="jdbcUrl" value="${jdbc.jdbcUrl}" ></property><property name="driverClass" value="${jdbc.driverClass}" ></property><property name="user" value="${jdbc.user}" ></property><property name="password" value="${jdbc.password}" ></property>
</bean><!-- 2.Dao-->
<bean name="accountDao" class="com.learn.dao.AccountDaoImpl" ><property name="dataSource" ref="dataSource" ></property>
</bean>
<!-- 3.Service-->
<bean name="accountService" class="com.learn.service.AccountServiceImpl" ><property name="ad" ref="accountDao" ></property><property name="tt" ref="transactionTemplate" ></property>
</bean>  </beans>
package com.learn.dao;public interface AccountDao {//加钱void increaseMoney(Integer id,Double money);//减钱void decreaseMoney(Integer id,Double money);
}
package com.learn.dao;import org.springframework.jdbc.core.support.JdbcDaoSupport;public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao  {@Overridepublic void increaseMoney(Integer id, Double money) {getJdbcTemplate().update("update t_account set money = money+? where id = ? ", money,id);}@Overridepublic void decreaseMoney(Integer id, Double money) {getJdbcTemplate().update("update t_account set money = money-? where id = ? ", money,id);}}
package com.learn.service;public interface AccountService {//转账方法void transfer(Integer from,Integer to,Double money);}
package com.learn.service;import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;import com.learn.dao.AccountDao;@Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=true)
public class AccountServiceImpl implements AccountService {private AccountDao ad ;private TransactionTemplate tt;@Override@Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=false)public void transfer(final Integer from,final Integer to,final Double money) {//减钱ad.decreaseMoney(from, money);int i = 1/0;//加钱ad.increaseMoney(to, money);}/*  @Overridepublic void transfer(final Integer from,final Integer to,final Double money) {tt.execute(new TransactionCallbackWithoutResult() {@Overrideprotected void doInTransactionWithoutResult(TransactionStatus arg0) {//减钱ad.decreaseMoney(from, money);int i = 1/0;//加钱ad.increaseMoney(to, money);}});}
*/public void setAd(AccountDao ad) {this.ad = ad;}public void setTt(TransactionTemplate tt) {this.tt = tt;}}
package com.learn.tx;import javax.annotation.Resource;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import com.learn.service.AccountService;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Demo {@Resource(name="accountService")private AccountService as;@Testpublic void fun1(){as.transfer(1, 2, 100d);}
}

spring事务管理-xml配置aop事务(重点)相关推荐

  1. spring事务管理-注解配置aop事务(重点)

    导包,导入新的约束,通知都不用配了,这两个是一样的,导包这一步,新的约束,tx这些都是一样的,第三步开始不同,这个注解配置大概一分钟就讲完了,第三步咱们可以开启注解,管理事务,那这块的话,咱们的配置文 ...

  2. Spring MVC 中使用AOP 进行事务管理--XML配置实现

    1.今天写一篇使用AOP进行事务管理的示例,关于事务首先需要了解以下几点 (1)事务的特性 原子性(Atomicity):事务是一个原子操作,由一系列动作组成.事务的原子性确保动作要么全部完成,要么完 ...

  3. Spring JDBC-使用XML配置声明式事务

    系列 概述 基于aop/tx命名空间的配置 示例 tx:method元素属性 系列 Spring对事务管理的支持概述以及 编程式的事务管理 Spring JDBC-使用XML配置声明式事务 Sprin ...

  4. Spring事务管理器配置两种配置方法,使用方法

    配置事务管理器 编程式事务管理: 要修改原来的代码,加入事务管理代码 (侵入性 )- 不推荐,不使用 声明式事务管理:底层就是AOP的环绕通知, - 推荐 用XML配置方式添加事务管理(tx.aop约 ...

  5. spring中基于XML的AOP配置步骤

    spring中基于XML的AOP配置步骤 IAccountService.java package com.itheima.service;/*** 账户的业务层接口*/ public interfa ...

  6. Struts2+spring+jdbc 以xml配置形式整合

    今天做作业,练习一下Struts2+spring+jdbc 以xml配置形式整合 整合步骤: 工程结构图: 重要配置文件 web.xml <?xml version="1.0" ...

  7. springboot项目中的注解 启动项目的方式 解决spring的bean.xml配置不生效 spring的基础JDBC配置

    依赖 创建一个 Spring Boot 工程时,可以继承自一个 spring-boot-starter-parent ,也可以不继承 先来看 parent 的基本功能有哪些? 定义了 Java 编译版 ...

  8. Spring——Bean管理-xml方式进行属性注入

    目录 一.xml方式创建对象 二.xml方式注入属性 第①种方式注入:set方法注入 第②种方式注入:有参构造函数注入 constructor-arg:通过构造函数注入 用name标签属性: 不按照顺 ...

  9. Spring框架----Spring的基于XML的AOP的实现

    导入依赖 <dependency><groupId>org.springframework</groupId><artifactId>spring-co ...

最新文章

  1. Linux系统性能分析:内存 优化
  2. jQuery 遍历后代
  3. nginx配置多个server
  4. Unity3d 下websocket的使用
  5. AutoBench+Httperf的安装、测试
  6. cocoa pods Installation
  7. 如何安装最新版本的 SAP ABAP Development Tool ( ADT ) 2021年度更新
  8. 浅谈Java和SAP ABAP的静态代理和动态代理,以及ABAP面向切面编程的尝试
  9. 前端学习(1161):箭头函数02
  10. javascript函数的声明,及返回值
  11. android 编译,gradle
  12. 那些年我们一起追过的ILSVRC冠军
  13. PPT之背景与标题搭配
  14. [业务流程图]与[数据流程图]的比较
  15. 技嘉显卡性能测试软件,显卡性能与超频:性能高于公版,超频潜力可圈可点
  16. 微信小程序无法获取个人信息,用户昵称变成了微信用户,怎么办
  17. 如何评价 IEEE Access 成为了 Top 期刊?
  18. 在Ubuntu18.04中使用gazebo配合LOAM算法仿真
  19. 微软TTS服务器,微软TTS,Neospeech TTS 简单使用
  20. html数字拼图游戏,JavaScript_JS写的数字拼图小游戏代码[学习参考],复制代码 代码如下:html - phpStudy...

热门文章

  1. stm32 DMA使用详解
  2. React单页如何规划路由、设计Store、划分模块、按需加载
  3. 基于MaxCompute打造轻盈的人人车移动端数据平台
  4. 错误 LINK : fatal error LNK1158: 无法运行“rc.exe”
  5. Docker服务器的图形显示方案
  6. mysql三:表操作
  7. Linux系统直接升级GLIBC版本
  8. 服务提供商应该如何帮助企业保护数据安全
  9. 让人难过的 openssl_pkcs7_encrypt
  10. LINK : fatal error LNK1104: cannot open file mfc42d.lib