Spring学习(五)事务管理
Spring 事务管理:
一、事务概念:
1、什么是事务?
事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做。
事务的结束有两种,当事务中的所以步骤全部成功执行时,事务提交。如果其中一个步骤失败,将发生回滚操作,撤消撤消之前到事务开始时的所以操作
2、事务的特性?
事务有四个特性:
(1)原子性:事务是数据库的逻辑工作单位,事务中包含的各操作要么都做,要么都不做
(2)一致性:事 务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。因此当数据库只包含成功事务提交的结果时,就说数据库处于一致性状态。如果数据库系统 运行中发生故障,有些事务尚未完成就被迫中断,这些未完成事务对数据库所做的修改有一部分已写入物理数据库,这时数据库就处于一种不正确的状态,或者说是 不一致的状态。
(3)隔离性:一个事务的执行不能其它事务干扰。即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。
(4)持久性:指一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的。接下来的其它操作或故障不应该对其执行结果有任何影响。
3、不考虑隔离性,产生的读问题?
(1)脏读:脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。
(2)不可重复读:事务A多次读取数据,同时事务B对该数据修改并且提交,导致事务A读到的数据不一致
(3)幻读:在事务A读取数据的时候,事务B向数据中增加或者删除数据,导致事务读取的数据与原读取的数据不一致
4、解决读问题?
设置隔离级别
二、Spring中的事务管理API
1、Spring事务管理方式
第一种方式:编程式事务管理(一般不用)
第二种方式:生命式事务管理
(1)基于xml配置文件
(2)基于注解方式
2、spring事务管理的api介绍
Spring事务管理高层抽象主要包括3个接口:
(1)PlatformTransactionManager:事务管理器
Spring针对不同的dao层框架,提供接口不同的实现类:

- 首先要配置事务管理器
-
(2)TransactionDefinition:事务定义信息(隔离、传播、超时、只读)
(3)TransactionStatus:事务具体运行状态
三、搭建转账的环境
1、创建数据库,表account

2、创建service 和 dao 类,完成注入关系
(1)service 又叫业务逻辑层
(2)dao 层单纯对数据库操作,在 dao 层不添加业务
(3)具体的需求,张三转账1000给李四
张三少了1000
李四多了1000
采用事务,解决了数据的不一致性等问题,采用声明式的事务管理方式(xml配置)和声明式的事务管理(注解方式)
- 声明式的事务管理方式(xml配置)
OrdersService.java
package com.itcast.service;
import cn.itcast.dao.OrdersDao;
public class OrdersService {
private OrdersDao ordersDao;
public void setOrdersDao(OrdersDao ordersDao) {
this.ordersDao = ordersDao;
}
//调用Dao方法
//业务逻辑层
public void accountMoney(){
//减少钱
ordersDao.lessMoney();
//增加层
ordersDao.moreMoney();
}
}
OrdersDao.java
package cn.itcast.dao;
import org.springframework.jdbc.core.JdbcTemplate;
public class OrdersDao {
//注入属性JDBCTemplate
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
//减少钱的方法
public void lessMoney(){
String sql="update account set salary=salary-? where username=?";
jdbcTemplate.update(sql,1000,"zhangsan");
}
//增加钱的方法
public void moreMoney(){
String sql="update account set salary=salary+? where username=?";
jdbcTemplate.update(sql,1000,"lisi");
}
}
使用AspectJ 的XML 配置声明式事务
(1)配置事务管理器
(2)配置事务增强器
(3)配置AOP切面产生代理
<!-- 第一步:配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入dataSource -->
<property name="dataSource" ref="dataSource"></property>
</bean> <!--第二步: 配置事务的增强 -->
<tx:advice id="txadvice" transaction-manager="transactionManager">
<!--做事务操作 -->
<tx:attributes>
<!-- 设置进行事务操作的方法匹配规则 -->
<!-- 如果方法以account开头,都可以用事务规则 -->
<tx:method name="account*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- 第三步:配置AOP切面 -->
<aop:config>
<!-- 1、切入点 -->
<aop:pointcut expression="execuyion(* com.itcast.service.OrdersService.*(..))" id="pointcut1"/>
<!-- 2、切面 -->
<aop:advisor advice-ref="txadvice" pointcut-ref="pointcut1"/>
</aop:config>
完整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:content="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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.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">
<!-- bean definitions here --> <!-- 配置 c3p0 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 注入属性值 -->
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property>
<property name="user" value="root"></property>
<property name="password" value="123"></property>
</bean> <!-- 第一步:配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入dataSource -->
<property name="dataSource" ref="dataSource"></property>
</bean> <!--第二步: 配置事务的增强 -->
<tx:advice id="txadvice" transaction-manager="transactionManager">
<!--做事务操作 -->
<tx:attributes>
<!-- 设置进行事务操作的方法匹配规则 -->
<!-- 如果方法以account开头,都可以用事务规则 -->
<tx:method name="account*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- 第三步:配置AOP切面 -->
<aop:config>
<!-- 1、切入点 -->
<aop:pointcut expression="execuyion(* com.itcast.service.OrdersService.*(..))" id="pointcut1"/>
<!-- 2、切面 -->
<aop:advisor advice-ref="txadvice" pointcut-ref="pointcut1"/>
</aop:config> <!-- 配置对象 -->
<bean id="ordersService" class="com.itcast.service.OrdersService">
<!-- 注入dao 对象 -->
<property name="ordersDao" ref="ordersDao"></property>
</bean>
<bean id="ordersDao" class="cn.itcast.dao.OrdersDao">
<!-- 注入模板 -->
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean> <!-- 创建JdbcTemplate对象 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!-- 把dataSource 传到 jdbcTemplate里面-->
<property name="dataSource" ref="dataSource"></property>
</bean> </beans>
测试代码:
@Test
public void test(){
ApplicationContext context =new ClassPathXmlApplicationContext("orders.xml");
OrdersService ordersService=(OrdersService) context.getBean("ordersService");
ordersService.accountMoney();
}
- 声明式的事务管理方式(注解方式)
(1)配置事务管理器
(2)配置事务注解
(3)在要使用事务的方法所在的类上面添加注解
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:content="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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.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">
<!-- bean definitions here --> <!-- 配置 c3p0 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 注入属性值 -->
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property>
<property name="user" value="root"></property>
<property name="password" value="123"></property>
</bean> <!--(1)配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- (2)开启事务的注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- (3)在要使用事务的方法所在的类上面添加注解 --> <!-- 配置对象 -->
<bean id="ordersService" class="com.itcast.service.OrdersService">
<!-- 注入dao 对象 -->
<property name="ordersDao" ref="ordersDao"></property>
</bean>
<bean id="ordersDao" class="cn.itcast.dao.OrdersDao">
<!-- 注入模板 -->
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean> <!-- 创建JdbcTemplate对象 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!-- 把dataSource 传到 jdbcTemplate里面-->
<property name="dataSource" ref="dataSource"></property>
</bean> </beans>
OrdersService.java
package com.itcast.service; import org.springframework.transaction.annotation.Transactional; import cn.itcast.dao.OrdersDao; @Transactional
public class OrdersService { private OrdersDao ordersDao; public void setOrdersDao(OrdersDao ordersDao) {
this.ordersDao = ordersDao;
}
//调用Dao方法
//业务逻辑层
public void accountMoney(){
//减少钱
ordersDao.lessMoney();
//如果发生异常,数据库自动回滚
double i=2/0;
//增加层
ordersDao.moreMoney();
}
}
Spring学习(五)事务管理的更多相关文章
- Spring学习8-Spring事务管理
http://blog.sina.com.cn/s/blog_7ffb8dd501014e0f.html Spring学习8-Spring事务管理(注解式声明事务管理) 标签: spring注 ...
- Spring基础学习(五)—事务管理
一.事务基本认识 1.事务的概述 为了保证数据库中数据的一致性,数据的操作应当是离散的成组的逻辑单元.当它全部完成时,数据的一致性可以保持,而当这个单元中的一部分操作失败,整个事务应当全部视 ...
- Spring学习8-Spring事务管理(AOP/声明式式事务管理)
一.基础知识普及 声明式事务的事务属性: 一:传播行为 二:隔离级别 三:只读提示 四:事务超时间隔 五:异常:指定除去RuntimeException其他回滚异常. 传播行为: 所谓事务的传播行为 ...
- Spring学习8-Spring事务管理(注解式声明事务管理)
步骤一.在spring配置文件中引入<tx:>命名空间 <beans xmlns="http://www.springframework.org/schema/beans& ...
- Spring学习8-Spring事务管理(编程式事务管理)
一.Spring事务的相关知识 1.事务是指一系列独立的操作,但在概念上具有原子性. 比如转账:A账号-100, B账号+100,完成.这两个操作独立是没问题的. 但在逻辑上,要么全部完成,要么一 ...
- spring深入学习(五)-----spring dao、事务管理
访问数据库基本是所有java web项目必备的,不论是oracle.mysql,或者是nosql,肯定需要和数据库打交道.一开始学java的时候,肯定是以jdbc为基础,如下: private sta ...
- Spring中的事务管理详解
在这里主要介绍Spring对事务管理的一些理论知识,实战方面参考上一篇博文: http://www.cnblogs.com/longshiyVip/p/5061547.html 1. 事务简介: 事务 ...
- Spring编程式事务管理及声明式事务管理
本文将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. Spring 事务属性分析 事务管理 ...
- Spring声明式事务管理与配置介绍
转至:http://java.9sssd.com/javafw/art/1215 [摘要]本文介绍Spring声明式事务管理与配置,包括Spring声明式事务配置的五种方式.事务的传播属性(Propa ...
- spring 声明式事务管理详解
前言:spring框架对于事务管理提供了两种方案.一,编程式事务.二,声明式事务.本例主要剖析 声明式事务. 何为声明式事务: 通过spring的配置文件配置事务规则,或使用spring @Trans ...
随机推荐
- jquery鼠标悬停事件hover()
在JQuery中提供了.hover()事件,hover的第一个参数(匿名方法)表示mouseenter,第二个参数表示mouseleave,即表示可以为hover传递两个参数.如下代码所示: $( & ...
- IDEA常用快捷键整理
快速定位文件: Ctrl+E,最近的文件 Ctrl+Shift+E,最近更改的文件 Alt+Shift+C,最近打开的文件 Ctrl+N,快速打开类 Ctrl+Shift+N,快速打开文件 当 ...
- 接口Comparator和Comparable的区别和联系
1. Comparator 和 Comparable 相同的地方 他们都是java的一个接口, 并且是用来对自定义的class比较大小的. 什么是自定义class: 如 public class Pe ...
- RS-485半双工延时问题
学习485总线时,遇到延时问题,困扰很久.通过学习知道了485半双工收发时必须延时,以保证系统的稳定性.可靠性.好多资料都介绍了485 防静电.抗干扰电路.惟独没提 每一帧收发停止位(或第9位)的延时 ...
- 关于jquery登录的一些简单验证。
获取值之后的判断 $(function () { $("#btlogin").click(function () { var txtaccount = $("#txtac ...
- linux日常管理-free查看内存工具
查看内存 命令 free 默认是k为单位 也可以指定 m为单位 或者G为单位,这个不精准 total 总容量 used 使用了多少 free 剩余多少 看第二行.第一行是物理内存,加上虚拟内存b ...
- [poj1273]Drainage Ditches(最大流)
解题关键:最大流裸题 #include<cstdio> #include<cstring> #include<algorithm> #include<cstd ...
- Tournament
题意: 有 $n$ 个 $K$ 维向量,若向量A只要有任意一维大于向量B,则认为A可能打败B,将n个向量一个一个加入,求问对于每次加完后的向量集合:有几个向量可能活到最后. 解法: 考虑如果A可以打败 ...
- Hibernate存储date/datetime问题,解决java的date与mysql的datetime不兼容
主要原因是出在Hibernate的配置文件中. 症状 1. java文件类型java.util.Date,数据库类型datetime,Hibernate配置文件用date,存储进数据库的时间只有年月日 ...
- 【转】Subversion快速入门教程-动画演示
如何快速建立Subversion服务器,并且在项目中使用起来,这是大家最关心的问题,与CVS相比,Subversion有更多的选择,也更加的容易,几个命令就可以建立一套服务器环境,可以使用起来,这里配 ...