学习了AOP之后就可以应用一下了,所以这次我们了解一下Spring的声明式事务。

事务在我们的很多方面都可以体现,就拿我们平时的买卖活动,或者是银行的转账来说,这些活动要么是成功,要么是失败,比如:张三给李四转账100块钱,我们的实现是张三的账户划掉100然后李四的账户加上100,这是一个整体,要么成功,要么失败。我们不可能说张三的账户少了钱,但是因为某种原因导致李四的账户没多钱。所以说我们要通过某种机制保证这个整体活动的成功。接下来进入主题。

  

1. Spring事务简介

1.1 事务的四要素

名称 内容
原子性(atomicity) 整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。
一致性(consistency) 一个事务可以封装状态改变(除非它是一个只读的)。事务必须始终保持系统处于一致的状态,不管在任何给定的时间并发事务有多少。
隔离性(isolation) 隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。
持久性(durability) 在事务完成以后,该事务对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。

1.2 Spring事务管理方式

  • 编程式事务

    编程式事务从名字应该可以看出,就是事务的管理方式由自己编写代码来实现,主要的实现方式就是通过对事务的代码嵌入进去我们的业务代码之中
  • 声明式事务

    声明事务主要是利用了Spring AOP通过面向切面编程把事务代码直接嵌入事务代码中,所以这里我们获取到的有事务管理的Bean实际上是Spring经过加工之后的代理类

概念性的东西不是内行,关于Spring事务的一些概念性的东西可以参考一下链接,希望有帮助

事务简介

|-https://baike.baidu.com/item/acid/10738?fr=aladdin

Spring事务

|-http://www.cnblogs.com/ysxlin/archive/2008/06/06/1215300.html

|- http://lxy2330.iteye.com/blog/1122183

|- http://www.cnblogs.com/longshiyVip/p/5061637.html

2. Spring事务准备工作

现在有两个人需要进行转账工作,我这里就随便的设计了这么一个剧情了,首先有一个dao(Data Access Object数据访问对象,与数据库打交道,这里我没有使用接口来实现,但是在一般的应用中是需要用接口实现的)

//这里继承了JdbcTemplate主要是方便实现,它对我们的Jdbc进行了封装,可以使我们不用考虑数据库连接关闭等等的问题
//而且此次的Spring事务主要是说的Jdbc事务
public class TransferDao extends JdbcTemplate { /**
* 将钱的数目转向当前user的账户
* @param money money
* @param username username
*/
public void transferMoneyToOne(Float money, String username){
this.update("UPDATE account SET money = money + (?) WHERE username = ?", money, username);
}
}

还有一个service(这里主要是写我们业务相关的代码)

public class TransferService {

    private TransferDao dao;

	/**
* 转账业务,这里为了方便直接写了张三转给了李四100块钱
*/
public void transferMoney(){
dao.transferMoneyToOne((float) -100, "张三");
// int i = 1 / 0;//为了测试出现异常的情况,测试时可去掉
dao.transferMoneyToOne((float) 100, "李四");
// throw new RuntimeException("这里突然死机了");//测试时可去掉
} public TransferDao getDao() {
return dao;
} public void setDao(TransferDao dao) {
this.dao = dao;
}
}

上面注释抛出的异常和代码错误主要是为了等下代码测试的时候模拟我们日常中可能出现的各种错误

这里还需要一个数据库和表(数据库自建,表的sql在下方)

-- ----------------------------
-- Table structure for man
-- ----------------------------
DROP TABLE IF EXISTS `account`;
CREATE TABLE `account` (
`username` varchar(255) default NULL,
`money` float(255,0) default NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ----------------------------
-- Records of man
-- ----------------------------
INSERT INTO `account` VALUES ('张三', '9600');
INSERT INTO `account` VALUES ('李四', '970');

3. Spring事务配置

事务需要加入的依赖较之前的需要加入tx依赖而且涉及数据库操作需要mysql连接包以及数据库连接池,这里使用的是阿里的druid,maven的pom.xml依赖主要如下:

 <properties>
<spring.version>4.3.10.RELEASE</spring.version>
</properties> <dependencies>
<!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency> <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.31</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.44</version>
</dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>RELEASE</version>
</dependency>
</dependencies>

以下是classpath下的applicationContext.xml配置文件

因为是事务配置与之前的相比需要加入tx命名约束

<?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"
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-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"> <!--配置DataSource-->
<bean name="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<!--以下是数据库连接的具体信息-->
<property name="username" value="root"/>
<property name="password" value="root"/>
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/spring_demo_1"/>
</bean> <!--配置TransferDao-->
<bean class="cn.lger.dao.TransferDao" name="transferDao">
<property name="dataSource" ref="dataSource"/>
</bean> <!--配置TransferService-->
<bean name="transferService" class="cn.lger.service.TransferService">
<property name="dao" ref="transferDao"/>
</bean> <!--配置管理事务的类-->
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean> <!--给定管理事务的类 设置通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--
这里设置需要事务操作的方法(切入点),
其中还有一些属性没有写,这里全部采用默认操作,
*为全部都需要事务操作
-->
<tx:method name="*"/>
</tx:attributes>
</tx:advice> <!--配置切面-->
<aop:config>
<!--设置切入点-->
<aop:pointcut id="txPointcut" expression="execution(* cn.lger.service.TransferService.*(..))"/>
<!--给定之前配置的通知-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
</aop:config> </beans>

在上面的tx通知配置中<tx:method name="*"/>,注释写明了采用默认的操作,但是这里还是提一下,<tx:method name="被代理方法名(需要事务管理的方法)" propagation="传播行为" read-only="是否只读" isolation="隔离级别" timeout="事务所需最大时间"/> 这里不作赘述,下面的链接我个人觉得解释的很好

事务配置之<tx:method/> 有关的设置

http://blog.sina.com.cn/s/blog_4a40057401000865.html

http://www.iteye.com/topic/410461

4. Spring事务测试

经过以上的准备工作以及配置这个项目已经能够运行了,所以,我们现在来测试一下当没有发生异常的情况下是否能够转账成功

public class TestTx {

    /**
* 测试service的转账功能
*/
@Test
public void test01(){
ApplicationContext context =
new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
TransferService service = context.getBean(TransferService.class);
service.transferMoney();
}
}

经过测试张三成功地转账给了李四100元,然后我们把之前的TransferService的异常的注释给去掉,然后进行测试,发现数据库中的数据稳如泰山,不会变,这就是事务,当抛出异常时会影响事务的ACID四要素,这个整体活动当然不会成功执行,所以,你看到的这就是事务。

上面代码可以在Github下载

我的Spring学习记录(三)的更多相关文章

  1. Spring学习记录(三)---bean自动装配autowire

    Spring IoC容器可以自动装配(autowire)相互协作bean之间的关联关系,少写几个ref autowire: no ---默认情况,不自动装配,通过ref手动引用 byName---根据 ...

  2. Spring学习记录(三)

    一.AOP的整理总结 aop面向切面编程 横向重复代码,纵向抽取 动态代理 1.通过动态代理可以体现aop思想 2.为什么要哦用动态代理:对目标对象中的方法进行增强 spring aop开发 spri ...

  3. 我的Spring学习记录(五)

    在我的Spring学习记录(四)中使用了注解的方式对前面三篇做了总结.而这次,使用了用户登录及注册来对于本人前面四篇做一个应用案例,希望通过这个来对于我们的Spring的使用有一定的了解. 1. 程序 ...

  4. Spring 学习记录8 初识XmlWebApplicationContext(2)

    主题 接上文Spring 学习记录7 初识XmlWebApplicationContext refresh方法 refresh方法是定义在父类AbstractApplicationContext中的. ...

  5. MyEclipse Spring 学习总结三 SpringMVC

    MyEclipse Spring 学习总结三 SpringMVC 一.SpringMVC原理 1.Springmvc 框架介绍 1)Spring 框架停工了构建Web应用程序的全功能MVC模块.Spr ...

  6. 我的Spring学习记录(二)

    本篇就简单的说一下Bean的装配和AOP 本篇的项目是在上一篇我的Spring学习记录(一) 中项目的基础上进行开发的 1. 使用setter方法和构造方法装配Bean 1.1 前期准备 使用sett ...

  7. 我的Spring学习记录(四)

    虽然Spring管理这我们的Bean很方便,但是,我们需要使用xml配置大量的Bean信息,告诉Spring我们要干嘛,这还是挺烦的,毕竟当我们的Bean随之增多的话,xml的各种配置会让人很头疼. ...

  8. Spring 学习记录3 ConversionService

    ConversionService与Environment的关系 通过之前的学习(Spring 学习记录2 Environment),我已经Environment主要是负责解析properties和p ...

  9. Spring 学习记录6 BeanFactory(2)

    主题 除了Spring 学习记录5 BeanFactory 里写的几个接口外,BeanFactory的实现类还实现了一些其他接口,这篇文章主要介绍这些接口和实现类. 结构 DefaultListabl ...

  10. spring 学习(三):aop 学习

    spring 学习(三):aop 学习 aop 概念 1 aop:面向切面(方面)编程,扩展功能不修改源代码实现 2 AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码 3 aop底层使用动态代 ...

随机推荐

  1. Jmeter之解决烦人的中文乱码问题

    Jmeter是一款国外开源工具,所以就跟LR一样,对中文的支持不是很好,经常会有同学录制脚本后回放或者是发送HTTP请求,看到响应报文里面有乱码! 那如何才能解决这个问题呢?我们分2个情况来分析: 一 ...

  2. amoeba

    Amoeba 原理:amoeba相当于业务员,处理client的读写请求,并将读写请求分开处理.amoeba和master以及slave都有联系,如果是读的请求,amoeba就从slave读取信息反馈 ...

  3. python注释方法以及编码问题

    一.单行注释 在python中常使用"#"来进行单行注释,其快捷键为"ctrl+/",如果要对多行代码也就是代码块进行注释时,也可以选中多行按下 "c ...

  4. MongoDb 入门教程

    MongoDb 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的. 它是可扩展的高性能数据存储解决方案,经常被用于非关系型数据的存储,能存储海量的数据. 常 ...

  5. (转载)理解Java中的引用传递和值传递

      关于Java传参时是引用传递还是值传递,一直是一个讨论比较多的话题,有论坛说Java中只有值传递,也有些地方说引用传递和值传递都存在,比较容易让人迷惑.关于值传递和引用传递其实需要分情况看待,今天 ...

  6. SQL查询语句分类

    SQL查询语句有多种,下面总结下.首先先建三张表用于后面的实验 -- 学生表,记录学生信息 CREATE TABLE student( sno ), sname ), ssex ENUM('男','女 ...

  7. Spark 贝叶斯分类算法

    一.贝叶斯定理数学基础 我们都知道条件概率的数学公式形式为 即B发生的条件下A发生的概率等于A和B同时发生的概率除以B发生的概率. 根据此公式变换,得到贝叶斯公式:  即贝叶斯定律是关于随机事件A和B ...

  8. 基于NIOS-II的示波器:PART1 按键&显示屏驱动&界面

    NIOS II 相关资料以及基础入门 <NiosII的奇幻漂流> <Nios II那些事儿> 本文所有的硬件基础以及工程参考来自魏坤示波仪,重新实现驱动并重构工程. 基于NIO ...

  9. 软件工程(GZSD2015)第三次作业提交进度

    第三次作业题目请查看这里:软件工程(GZSD2015)第三次作业 开始进入第三次作业提交进度记录中,童鞋们,虚位以待哈... 2015年4月19号 徐镇.尚清丽,C语言 2015年4月21号 毛涛.徐 ...

  10. 微信小程序xml解析

    准备: 下载xmldom库:https://github.com/jindw/xmldom 将dom.js.dom-parser.js.sax.js,entities.js拷贝微信小程序需要的文件夹下 ...