一、对事务的支持

事务:是一组原子操作的工作单元,要么全部成功,要么全部失败

Spring管理事务方式:

  • JDBC编程事务管理:--可以控制到代码中的行

可以清楚的控制事务的边界,事务控制粒度化细(编程的方式

  • JDBC声明事务管理---可以控制到方法

事务相关API不用介入程序之中,将事务管理与实际业务代码解耦合(配置XML的方式)

二、JDBC编程事务管理

Spring提供两种方式实现编程式的事务管理:

  • 实现PlatformTransactionManager接口
  • 使用TransactionTemplate模式

2.1、实现PlatformTransactionManager接口

大致步骤:

  • 指定PlatformTransactionManager的实现类
  • 定义事务TransactionDefinition
  • 将事务定义传送给TransactionStatus
  • 将欲进行的事务用try..catch语句封起来
  • 如果事务出错,调用PlatformTransactionManager的rollback方法
package com.pb.transaction.demo;

import javax.sql.DataSource;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition; /**
* 使用TransactionManager事务管理
* 缺点:侵入代码
* 优点:控制度细粒度
*/
public class TransactionManagerDemo { public static void main(String[] args) {
ClassPathXmlApplicationContext cpx=new ClassPathXmlApplicationContext("applicationContext.xml");
//获取platform对象
PlatformTransactionManager ptm=(PlatformTransactionManager) cpx.getBean("transactionManager");
//事务定义器
DefaultTransactionDefinition dtd=new DefaultTransactionDefinition();
//设置事务定义器的行为
dtd.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRED);
//事务状态通过事务管理器创建
TransactionStatus ts=ptm.getTransaction(dtd); //进行事务 try {
//获取数据源
DataSource ds=(DataSource) cpx.getBean("dataSource");
//创建JDBCTemplacte
JdbcTemplate jt=new JdbcTemplate(ds);
//执行更新或者插入等操作
jt.update("insert into person values(11,'TTM',23)");
jt.update("update person set name='张王八' where id=7");
ptm.commit(ts); System.out.println("===========");
} catch (Exception e) {
ptm.rollback(ts);
System.out.println("撤消=======");
e.printStackTrace();
} } }

2.2、使用TransactionTemplate模式

大致步骤:

  • 需要封装一个TransactionManager
  • 创建事务回滚类
  • 执行TransactionManager的execute()方法
package com.pb.transaction.demo;

import javax.sql.DataSource;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate; /**
* 使用TransactionTemplate事务管理 缺点:侵入代码 优点:控制度细粒度
*/
public class TransactionTeplateDemo { public static void main(String[] args) {
ClassPathXmlApplicationContext cpx = new ClassPathXmlApplicationContext(
"applicationContext.xml");
// 获取platform对象
PlatformTransactionManager ptm = (PlatformTransactionManager) cpx
.getBean("transactionManager");
// 事务模版
TransactionTemplate tt = new TransactionTemplate(ptm);
// 获取数据源
DataSource ds = (DataSource) cpx.getBean("dataSource");
// 创建JDBCTemplacte
final JdbcTemplate jt = new JdbcTemplate(ds);
// 进行事务回调函数
tt.execute(new TransactionCallbackWithoutResult() { @Override
protected void doInTransactionWithoutResult(TransactionStatus arg0) {
// 执行更新或者插入等操作
jt.update("insert into person values(17,'TOM',23)");
jt.update("update person set name='李四3' where id=4"); }
}); } }

2.3、编程事务配置

<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> <!-- 声明数据源 org.springframework.jdbc.datasource.DriverManagerDataSource/com.mchange.v2.c3p0.ComboPooledDataSource-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<!--驱动 -->
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<!--url -->
<property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
<!--用户名 -->
<property name="username" value="accp"/>
<!--密码 -->
<property name="password" value="accp"/>
</bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>

三、JDBC声明事务管理

主要通过AOP功能实现

不需要修改原有的类

使用TransationProxyFactoryBean指定要介入的事务以及方法

实体类:数据库中有与之相对应的表

package com.pb.entity;

public class Person {
private Long id;
private String name;
private Integer age;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
} }

dao和实现类

package com.pb.dao;

import java.util.List;

import com.pb.entity.Person;

public interface PersonDao {

    public int insert(Person p);

    public int batchInsert(List<Person> persons);

}
//实现类
package com.pb.dao.impl; import java.util.List; import javax.sql.DataSource; import org.springframework.jdbc.core.JdbcTemplate; import com.pb.dao.PersonDao;
import com.pb.entity.Person; public class PersonDaoImpl implements PersonDao {
private JdbcTemplate jdbcTemplate; public void setDataSource(DataSource ds){
jdbcTemplate=new JdbcTemplate(ds);
}
@Override
public int insert(Person p) {
String sql="insert into person values(?,?,?)";
Object [] params={p.getId(),p.getName(),p.getAge()};
return jdbcTemplate.update(sql,params);
} @Override
public int batchInsert(List<Person> persons) {
int count=0;
for (Person person : persons) {
insert(person);
count++;
}
return count;
} }

测试类

package com.pb.transation.aop.demo;

import java.util.ArrayList;
import java.util.List; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.pb.dao.PersonDao;
import com.pb.entity.Person; public class FirstAOPTransationDemo { public static void main(String[] args) {
ClassPathXmlApplicationContext cpx=new ClassPathXmlApplicationContext("applicationContext.xml");
//这里调用代理的类
PersonDao personDao=(PersonDao) cpx.getBean("personDaoProxy"); Person p1=new Person();
p1.setId(new Long(28));
p1.setName("朱雀");
p1.setAge(199);
Person p2=new Person();
p2.setId(new Long(29));
p2.setName("玄武");
p2.setAge(150);
List<Person> persons=new ArrayList<Person>();
persons.add(p1);
persons.add(p2);
int count=personDao.batchInsert(persons);
System.out.println("更新了,"+count+"条记录"); } }

applicationContext.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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> <!-- 声明数据源 org.springframework.jdbc.datasource.DriverManagerDataSource/com.mchange.v2.c3p0.ComboPooledDataSource-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<!--驱动 -->
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<!--url -->
<property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
<!--用户名 -->
<property name="username" value="accp"/>
<!--密码 -->
<property name="password" value="accp"/>
</bean>
<!--接口实现类 -->
<bean id="personDao" class="com.pb.dao.impl.PersonDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="personDaoProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<!--指定接口 -->
<property name="proxyInterfaces" >
<list>
<value>com.pb.dao.PersonDao</value>
</list>
</property>
<!-- 管理的目标 -->
<property name="target" ref="personDao"/>
<!--注入事务管理 -->
<property name="transactionManager" ref="transactionManager"></property>
<!--事务管理的方法 和方式 -->
<property name="transactionAttributes">
<props>
<prop key="batch*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean> </beans>

四、事务的属性

声明式事务以方法为边界,简单的讲,一个方法被看成一个事务

Spring中事务的属性:

  • 传播行为(Propagation Behavior)
  • 隔离级别(Lsolation Level)
  • 只读提示(Rean-only Hints)
  • 事务超时期限(The Transaction Timeout period)

4.1、传播行为

4.2、隔离级别

五、Spring2.0后声明式事务管理:基于XMLSchema

步骤:

  1. 加入相关的XML命名空间
  2. 使用<tx:advice>标签指定Advice
  3. 使用<aop:config>标签配置事务管理
<?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:p="http://www.springframework.org/schema/p"
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-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd"> <!-- 声明数据源 org.springframework.jdbc.datasource.DriverManagerDataSource/com.mchange.v2.c3p0.ComboPooledDataSource-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<!--驱动 -->
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<!--url -->
<property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
<!--用户名 -->
<property name="username" value="accp"/>
<!--密码 -->
<property name="password" value="accp"/>
</bean>
<!--接口实现类 -->
<bean id="personDao" class="com.pb.dao.impl.PersonDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--事务管理的类 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--指明事务管理 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--指定方法和方式 -->
<tx:attributes>
<tx:method name="batch*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<aop:config>
<!--切入点 -->
<aop:pointcut expression="execution(* com.pb.dao.PersonDao.*(..) )" id="mypoint"/>
<!--关切入点和切入对象事务 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="mypoint"/>
</aop:config>
</beans>

六、基于注解的事务管理

package com.pb.dao.impl;

import java.util.List;

import javax.sql.DataSource;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import com.pb.dao.PersonDao;
import com.pb.entity.Person;
//在要管理的类下加上@transactional
@Transactional
public class PersonDaoImpl implements PersonDao {
private JdbcTemplate jdbcTemplate; public void setDataSource(DataSource ds){
jdbcTemplate=new JdbcTemplate(ds);
}
@Override
public int insert(Person p) {
String sql="insert into person values(?,?,?)";
Object [] params={p.getId(),p.getName(),p.getAge()};
return jdbcTemplate.update(sql,params);
}
//在要管理的方法下加上属性propagation=Propagation.REQUIRED
@Transactional(propagation=Propagation.REQUIRED)
public int batchInsert(List<Person> persons) {
int count=0;
for (Person person : persons) {
insert(person);
count++;
}
return count;
} }

配置文件中加入一条

<?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:p="http://www.springframework.org/schema/p"
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-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd"> <!-- 声明数据源 org.springframework.jdbc.datasource.DriverManagerDataSource/com.mchange.v2.c3p0.ComboPooledDataSource-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<!--驱动 -->
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<!--url -->
<property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
<!--用户名 -->
<property name="username" value="accp"/>
<!--密码 -->
<property name="password" value="accp"/>
</bean>
<!--接口实现类 -->
<bean id="personDao" class="com.pb.dao.impl.PersonDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--事务管理的类 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--指明注解方式的事务管理器 -->
<tx:annotation-driven transaction-manager="transactionManager"/> </beans>

Spring(九)Spring对事务的支持的更多相关文章

  1. Spring学习(十九)----- Spring的五种事务配置详解

    前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识.通过这次的学习发觉Spring的事务配置只要把思路理清,还是比较好掌握的. ...

  2. 全面分析 Spring 的编程式事务管理及声明式事务管理

    开始之前 关于本教程 本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本 ...

  3. Spring 中的 JDBC 事务

    Spring 对 JDBC 的支持 JdbcTemplate 简介 •为了使 JDBC 更加易于使用, Spring 在 JDBC API 上定义了一个抽象层, 以此建立一个 JDBC 存取框架. • ...

  4. 从源码分析 Spring 基于注解的事务

    在spring引入基于注解的事务(@Transactional)之前,我们一般都是如下这样进行拦截事务的配置: <!-- 拦截器方式配置事务 --> <tx:advice id=&q ...

  5. spring的annotation-driven配置事务管理器详解

    http://blog.sina.com.cn/s/blog_8f61307b0100ynfb.html ——————————————————————————————————————————————— ...

  6. 全面分析 Spring 的编程式事务管理及声明式事务管理--转

    开始之前 关于本教程 本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本 ...

  7. spring与hibernate整合事务管理的理解

    在谈Spring事务管理之前我们想一下在我们不用Spring的时候,在Hibernate中我们是怎么进行数据操作的.在Hibernate中我们每次进行一个操作的的时候我们都是要先开启事务,然后进行数据 ...

  8. Spring使用注解进行事务的管理

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

  9. spring中注解式事务不生效的问题

    常用的解决方法可以百度,我针对我的问题描述一下 Mysql中InnoDB引擎才支持事务, MyISAM不支持事务. 当你尝试了各种方法解决spring中注解式事务不生效时, 一定要查看一下数据库中表的 ...

随机推荐

  1. MyBatis知多少(23)MyBatis结果映射

    resultMap的元素是在MyBatis的最重要和最强大的元素.您可以通过使用MyBatis的结果映射减少高达90%的JDBC编码,在某些情况下,可以让你做JDBC不支持的事情. ResultMap ...

  2. SpringMVC 拦截器

    类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理. 常用场景: 1.日志记录:记录请求信息的日志,以便进行信息监控.信息统计.计算PV(Page View)等. 2.权限 ...

  3. c# File 操作

    //1.---------文件夹创建.移动.删除--------- //创建文件夹 Directory.CreateDirectory(Server.MapPath("a")); ...

  4. 玩转PowerShell第三节——【SCOM Maintenance Mode】-技术&分享

    概述 Microsoft System Center Operations Manager 2007 sp1(SCOM)是微软推出的专业系统监控软件,可以监控部署在网络中的服务器.应用系统和客户端,提 ...

  5. 后端码农谈前端(CSS篇)第一课:CSS概述

    一.从扮演浏览器开始 扮演浏览器是Head First图书中很有意义的一个环节.可作者忘记了告诉我们扮演浏览器的台本.我们从这里开始. 上图是webkit内核渲染html和css的流程图.从该图我们可 ...

  6. CentOS6.5菜鸟之旅:安装Realtek无线网卡驱动

    一.前言 CentOS6.5不像CentOS7和Unbuntu那样自动安装好了无线网卡驱动,因此需要我们折腾一下. 二.安装前的准备工作   [a] 检查无线网卡驱动的安装情况(通过查看网络接口的安装 ...

  7. BZOJ1003 物流运输 最短路+DP

    1003: [ZJOI2006]物流运输 Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条 ...

  8. AndroidStudio-OSX 常用快捷键整理

    整理完OSX的快捷键后自然少不了开发环境的快捷键了,暂时整理了些自己常用的 其实AS很多可能用得比较多的快捷键完全是跟MAC的文本编辑快捷键重复的,比如光标跳转和选择文本,这部分去那边参考就好   C ...

  9. Team Foundation Server简介

    对于任何一个软件开发团队而言,成功的一个重要因素在于成员之间.成员与首先使用软件的用户之间有很好的沟通. Team Foundation Server是一个独立的服务器产品,逻辑上,由下列两层组成,这 ...

  10. 团队项目2.0软件改进分析MathAPP

    软件改进分析 在此基础上,进行软件的改进. 首先,我们把这个软件理解成一个投入市场的.帮助小朋友进行算术运算练习的APP. 从质量保证的角度,有哪些需要改进的BUG? 从用户的角度(把自己当成小学生或 ...