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学习(五)事务管理的更多相关文章

  1. Spring学习8-Spring事务管理

      http://blog.sina.com.cn/s/blog_7ffb8dd501014e0f.html   Spring学习8-Spring事务管理(注解式声明事务管理) 标签: spring注 ...

  2. Spring基础学习(五)—事务管理

    一.事务基本认识 1.事务的概述      为了保证数据库中数据的一致性,数据的操作应当是离散的成组的逻辑单元.当它全部完成时,数据的一致性可以保持,而当这个单元中的一部分操作失败,整个事务应当全部视 ...

  3. Spring学习8-Spring事务管理(AOP/声明式式事务管理)

    一.基础知识普及 声明式事务的事务属性: 一:传播行为 二:隔离级别 三:只读提示 四:事务超时间隔 五:异常:指定除去RuntimeException其他回滚异常.  传播行为: 所谓事务的传播行为 ...

  4. Spring学习8-Spring事务管理(注解式声明事务管理)

    步骤一.在spring配置文件中引入<tx:>命名空间 <beans xmlns="http://www.springframework.org/schema/beans& ...

  5. Spring学习8-Spring事务管理(编程式事务管理)

    一.Spring事务的相关知识   1.事务是指一系列独立的操作,但在概念上具有原子性. 比如转账:A账号-100, B账号+100,完成.这两个操作独立是没问题的. 但在逻辑上,要么全部完成,要么一 ...

  6. spring深入学习(五)-----spring dao、事务管理

    访问数据库基本是所有java web项目必备的,不论是oracle.mysql,或者是nosql,肯定需要和数据库打交道.一开始学java的时候,肯定是以jdbc为基础,如下: private sta ...

  7. Spring中的事务管理详解

    在这里主要介绍Spring对事务管理的一些理论知识,实战方面参考上一篇博文: http://www.cnblogs.com/longshiyVip/p/5061547.html 1. 事务简介: 事务 ...

  8. Spring编程式事务管理及声明式事务管理

    本文将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. Spring 事务属性分析 事务管理 ...

  9. Spring声明式事务管理与配置介绍

    转至:http://java.9sssd.com/javafw/art/1215 [摘要]本文介绍Spring声明式事务管理与配置,包括Spring声明式事务配置的五种方式.事务的传播属性(Propa ...

  10. spring 声明式事务管理详解

    前言:spring框架对于事务管理提供了两种方案.一,编程式事务.二,声明式事务.本例主要剖析 声明式事务. 何为声明式事务: 通过spring的配置文件配置事务规则,或使用spring @Trans ...

随机推荐

  1. navicat导入sql文件

    Hello,大家好.Navicat是我们平时使用较多的一个数据库客户端工具,平时小天我主要是用来连接mysql的,使用的时候还是很方便的. 今天小天我就给大家分享一个Navicat如何导入导出sql文 ...

  2. HDOJ(1069)最长下降子序列

    每个箱子可有3种叠加方式,所以有3*n个箱子.将箱子按长度由大到小排序,有求箱子按宽度的最长下降子序列的高度之和即可. #include<cstdio> #include<algor ...

  3. 【转】 Pro Android学习笔记(三四):Menu(5):动态菜单

    目录(?)[-] OptionsMenu的创建方式 如何再次创建OptionsMenu 每次访问都重新填充菜单项 OptionsMenu的创建方式 OptionMenu在第一次访问该菜单时调用,只调用 ...

  4. loadrunner的四个主要部件

    1.VUser Generator :性能脚本开发 2.Controller :提供多线程并发操作 3.Analysis :结果分析 4.Load Generator :负载生成器 ***负载生成器完 ...

  5. PAT1106(BFS)

    PAT 1106 思路 BFS用在tree上,这一个题里主要关注的是用vector去保存每一个节点所连接的子节点,当BFS 时,一旦发现该节点下面没有子节点,这一层一定是最短的路径,然后用当前的层数去 ...

  6. css中的特殊居中

    大图居中: 先看一下普通的居中: 代码为: <!DOCTYPE html> <html lang="en"> <head> <meta c ...

  7. Android中EditTex焦点设置和弹不弹出输入法的问题(转)

    今天编程碰到了一个问题:有一款平板,打开一个有EditText的Activity会默认弹出输入法.为了解决这个问题就深入研究了下android中焦点Focus和弹出输入法的问题.在网上看了些例子都不够 ...

  8. Java enum(枚举)使用详解之三

    DK1.5引入了新的类型——枚举.在 Java 中它虽然算个“小”功能,却给我的开发带来了“大”方便. 用法一:常量 在JDK1.5 之前,我们定义常量都是: publicstaticfianl... ...

  9. Android M AudioPolicy 分析

    1.AudioPolicyService基础 AudioPolicy在Android系统中主要负责Audio"策略"相关的问题.它和AudioFlinger一起组成了Android ...

  10. VC 绘图,使用双缓冲技术实现

    VC 绘图,使用双缓冲技术实现 - Cloud-Datacenter-Renewable Energy-Big Data-Model - 博客频道 - CSDN.NET VC 绘图,使用双缓冲技术实现 ...