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.extend 函数详解
JQuery的extend扩展方法: Jquery的扩展方法extend是我们在写插件的过程中常用的方法,该方法有一些重载原型,在此,我们一起去了解了解. 一.Jquery的扩展方 ...
- DSP/BIOS程序启动顺序
基于TI的DSP芯片的应用程序分为两种:一般应用程序:DSP/BIOS应用程序. 为简化编程,TI提供了一套C的编程接口,它以API和宏的形式封装了TI的所有硬件模块,这套接口统称DSP/BIOS.D ...
- C#某月的第一天和最后一天
1.本月的第一天===>DateTime.Now.AddDays(1 - DateTime.Now.Day);//当前日期减去当前日期和本月一号相差天数 2.本月的最后一天===>Date ...
- SQL 常用语句收集
1.UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值 2.SELECT * FROM TableA INNER JOIN TableB ON TableA.name = T ...
- SEO优化-伪静态-URLRewrite 详解
下面是文章是我在网上看到的,觉得写的还不错,我拿过来,修改了一些作者没有说到的地方....... 1. 在apache中配置 2. 用URLRewrite(详细:重点是UrlRewrite+Strut ...
- 发一个可伸缩线程池大小的python线程池。已通过测试。
发一个可伸缩线程池大小的线程池. 当任务不多时候,不开那么多线程,当任务多的时候开更多线程.当长时间没任务时候,将线程数量减小到一定数量. java的Threadpoolexcutor可以这样,py的 ...
- k8s 基础 问题
vim /usr/lib/systemd/system/docker.service --insecure-registry registry.access.redhat.com \ ubelet.s ...
- jquery.html5uploader.js 上传控件
插件地址:http://blog.csdn.net/never_say_goodbye/article/details/8598521 先上个效果图: 相比来说,效果还是很不错的 使用MVC3做服务器 ...
- 网络编程中阻塞和非阻塞socket的区别
阻塞socket和非阻塞socket 建立连接阻塞方式下,connect首先发送SYN请求道服务器,当客户端收到服务器返回的SYN的确认时,则connect返回.否则的话一直阻塞.非阻塞方式,conn ...
- Robot Framework 接口自动化介绍
接口测试的重要性大家应该都清楚,就不多说了,本文中主要介绍接口测试如何在robot framework自动化测试框架中进行. 一.环境依赖 1.安装robot framework环境,本文中不做讲解 ...