概述

  编程式事务控制

    自己手动控制事务,就叫做编程式事务控制。

    Jdbc代码:

      Conn.setAutoCommite(false);  // 设置手动控制事务

    Hibernate代码:

      Session.beginTransaction();    // 开启一个事务

    【细粒度的事务控制: 可以对指定的方法、指定的方法的某几行添加事务控制】

    (比较灵活,但开发起来比较繁琐: 每次都要开启、提交、回滚.)

spring提供的事务控制

  声明式事务控制

    Spring提供了对事务的管理, 这个就叫声明式事务管理。

    Spring提供了对事务控制的实现。用户如果想用Spring的声明式事务管理,只需要在配置文件中配置即可; 不想使用时直接移除配置。这个实现了对事务  控制的最大程度的解耦。

    Spring声明式事务管理,核心实现就是基于Aop。

    【粗粒度的事务控制: 只能给整个方法应用事务,不可以对方法的某几行应用事务。】

    (因为aop拦截的是方法。)

    Spring声明式事务管理器类:

      Jdbc技术:DataSourceTransactionManager

      Hibernate技术:HibernateTransactionManager

 package cn.fuyi.a_tx;

 public class Dept {

     private Integer deptId;
private String dname;
public Integer getDeptId() {
return deptId;
}
public void setDeptId(Integer deptId) {
this.deptId = deptId;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
} } package cn.fuyi.a_tx; import org.springframework.jdbc.core.JdbcTemplate; public class DeptDao { private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
} public void save(Dept dept) {
String sql = "insert into dept(dname) values(?)";
jdbcTemplate.update(sql, dept.getDname());
}
} package cn.fuyi.a_tx; public class DeptService { private DeptDao deptDao;
public void setDeptDao(DeptDao deptDao) {
this.deptDao = deptDao;
} public void save(Dept dept) {
deptDao.save(dept);
int i = 1/0;
deptDao.save(dept); }
} <?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:context="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"> <!-- dataSource配置 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql:///mydb"></property>
<property name="user" value="root"></property>
<property name="password" value="950613"></property>
<property name="initialPoolSize" value="4"></property>
<property name="maxPoolSize" value="9"></property>
<property name="maxStatements" value="100"></property>
<property name="acquireIncrement" value="2"></property>
</bean> <!-- JdbcTemplate工具类实例 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean> <!-- dao实例 -->
<bean id="deptDao" class="cn.fuyi.a_tx.DeptDao">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean> <!-- service实例 -->
<bean id="deptService" class="cn.fuyi.a_tx.DeptService">
<property name="deptDao" ref="deptDao"></property>
</bean> <!-- spring的声明式事务配置 -->
<!-- 1.配置事务管理器类 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean> <!-- 2.配置事务增强(如何管理事务?) -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*save*" read-only="false" isolation="DEFAULT" propagation="REQUIRED"/>
<tx:method name="*find*" read-only="true" isolation="DEFAULT" propagation="REQUIRED"/>
<tx:method name="*get*" read-only="true" isolation="DEFAULT" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice> <!-- 3.AOP配置:拦截哪些方法(切入点表达式 + 应用上面的事务增强配置) -->
<aop:config>
<aop:pointcut expression="execution(* cn.fuyi.a_tx.DeptService.*(..))" id="pt"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/>
</aop:config> </beans> package cn.fuyi.a_tx; import static org.junit.Assert.*; import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class App { private ApplicationContext ac = new ClassPathXmlApplicationContext("cn/fuyi/a_tx/beans.xml"); @Test
public void testTx1() throws Exception {
DeptService ds = (DeptService) ac.getBean("deptService");
Dept dept = new Dept();
dept.setDname("哈2哈");
ds.save(dept);
}
} /**Output 数据库回滚 */

  注解方式实现

    使用注解实现Spring的声明式事务管理,更加简单!

    步骤:

  1) 必须引入Aop相关的jar文件

  2) bean.xml中指定注解方式实现声明式事务管理以及应用的事务管理器类

  3)在需要添加事务控制的地方,写上: @Transactional

   @Transactional注解:

  1)应用事务的注解

  2)定义到方法上: 当前方法应用spring的声明式事务

  3)定义到类上:   当前类的所有的方法都应用Spring声明式事务管理;

  4)定义到父类上: 当执行父类的方法时候应用事务。

 <?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:context="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"> <!-- 1. 数据源对象: 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:///hib_demo"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
<property name="initialPoolSize" value="3"></property>
<property name="maxPoolSize" value="10"></property>
<property name="maxStatements" value="100"></property>
<property name="acquireIncrement" value="2"></property>
</bean> <!-- 2. JdbcTemplate工具类实例 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean> <!-- 事务管理器类 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean> <!-- 开启注解扫描 -->
<context:component-scan base-package="cn.itcast.b_anno"></context:component-scan> <!-- 注解方式实现事务: 指定注解方式实现事务 -->
<tx:annotation-driven transaction-manager="txManager"/>
</beans>

事务属性

 @Transactional(
readOnly = false, // 读写事务
timeout = -1, // 事务的超时时间不限制
noRollbackFor = ArithmeticException.class, // 遇到数学异常不回滚
isolation = Isolation.DEFAULT, // 事务的隔离级别,数据库的默认
propagation = Propagation.REQUIRED // 事务的传播行为
)
public void save(Dept dept){
deptDao.save(dept);
int i = 1/0;
deptDao.save(dept);
}

事务传播行为:

  Propagation.REQUIRED

    指定当前的方法必须在事务的环境下执行;

    如果当前运行的方法,已经存在事务, 就会加入当前的事务;

  Propagation.REQUIRED_NEW

    指定当前的方法必须在事务的环境下执行;

    如果当前运行的方法,已经存在事务:  事务会挂起; 会始终开启一个新的事务,执行完后;  刚才挂起的事务才继续运行。

  举例:

 1.Propagation.REQUIRED  
Class Log{
@Propagation.REQUIRED  
insertLog();
} Class DeptDao{
@Propagation.REQUIRED
Void saveDept(){
insertLog(); // 加入当前事务
.. 出现异常, 会回滚
saveDept();
}
} 2.Propagation.REQUIRED_NEW  
Class Log{
@Propagation.REQUIRED_NEW  
insertLog();
} Class DeptDao{
@Propagation.REQUIRED
Void saveDept(){
insertLog(); // 始终开启事务
.. 异常, 日志不会回滚
saveDept();
}
}

  测试:

 package cn.fuyi.a_tx;

 import javax.annotation.Resource;

 import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; @Repository
public class LogDao { @Resource
private JdbcTemplate jdbcTemplate; @Transactional(propagation=Propagation.REQUIRES_NEW)
public void insertLog() {
String sql = "insert into log_ values('在保存dept。。。')";
jdbcTemplate.update(sql);
}
} package cn.fuyi.a_tx; import javax.annotation.Resource; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; @Service("deptService")
public class DeptService { @Resource(name="deptDao")
private DeptDao deptDao; @Resource(name="logDao")
private LogDao logDao; @Transactional(
propagation=Propagation.REQUIRED
)
public void save(Dept dept) {
logDao.insertLog();
int i = 1/0;
deptDao.save(dept);
}
}

 

spring来了-06-事务控制的更多相关文章

  1. spring基于注解的事务控制

    pom配置: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http ...

  2. spring基于xml的事务控制

    opm配置 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http: ...

  3. Spring 使用注解对事务控制详解与实例

    1.什么是事务 一荣俱荣,一损俱损,很多复杂的操作我们可以把它看成是一个整体,要么同时成功,要么同时失败. 事务的四个特征ACID: 原子性(Atomic):表示组成一个事务的多个数据库的操作的不可分 ...

  4. 笔面试复习(spring常用.jar包/事务/控制反转/bean对象管理和创建/springMVC工作原理/sql查询)

    ###spring常用jar包1.spring.jar是包含有完整发布模块的单个jar包.2.org.springframework.aop包含在应用中使用Spring的AOP特性时所需要的类.3.o ...

  5. spring boot 多数据源 + 事务控制

    1,首先在启动类加上@EnableTransactionManagement注解 package cn.bforce.common; import org.springframework.boot.S ...

  6. spring中编程式事务控制

    step1:配置xml文件 <!-- 事务管理bean --> <bean id="transactionManager" class="org.spr ...

  7. spring入门(三)【事务控制】

    在开发中需要操作数据库,进行增.删.改操作的过程中属于一次操作,如果在一个业务中需要更新多张表,那么任意一张表的更新失败,整个业务的更新就是失败,这时那些更新成功的表必须回滚,否则业务会出错,这时就要 ...

  8. Spring第八篇【XML、注解实现事务控制】

    前言 本博文主要讲解Spring的事务控制,如何使用Spring来对程序进行事务控制-. 一般地,我们事务控制都是在service层做的..为什么是在service层而不是在dao层呢??有没有这样的 ...

  9. Spring企业级程序设计 • 【第4章 Spring持久化层和事务管理】

    全部章节   >>>> 本章目录 4.1 配置数据源资源 4.1.1 JdbcTemplate介绍 4.1.2通过ComboPooledDataSource创建数据源 4.1. ...

随机推荐

  1. 在主类E的main方法中,创建类B 的对象并赋给父类A的对象a,使用上转型对象a来测试上转型对象的一些特性。

    public class A { private int a=1; public int getA() { return a; } public void setA(int a) { this.a = ...

  2. 粒子群优化算法(Particle Swarm Optimization)

    粒子群算法的思想源于对鸟/鱼群捕食行为的研究,模拟鸟集群飞行觅食的行为,鸟之间通过集体的协作使群体达到最优目的,是一种基于Swarm Intelligence的优化方法.它没有遗传算法的"交 ...

  3. 终止jQuery的$.ajax方法abort

    最近遇到,如果用户频繁点击ajax请求,有两个问题: 1,如果连续点击了5个ajax请求,前4个其实是无效的,趁早结束节省资源. 2,更严重的问题是:最后一个发送的请求,响应未必是最后一个,有可能造成 ...

  4. [POJ1681]Painter's Problem(高斯消元,异或方程组,状压枚举)

    题目链接:http://poj.org/problem?id=1681 题意:还是翻格子的题,但是这里有可能出现自由变元,这时候枚举一下就行..(其实这题直接状压枚举就行) /* ━━━━━┒ギリギリ ...

  5. XSS防御篇

    上周要求写自己用任何语言写一个留言版,存到数据库中,用自己的办法来解决XSS 我用了JSP+MYSQL,自己写了一个过滤器来防御WEB XSS漏洞 package com.mess.filter; p ...

  6. [C和指针]第四部分

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  7. iOS - OC NSCache 缓存

    前言 NSCache 是苹果提供的一个专门用来做缓存的类,当内存 "不足" 或超过限制的时候,会自动清理缓存,使用时可以指定缓存的数量和成本.用法与 NSMutableDictio ...

  8. Oracle数据库高级查询(五)集合查询

    现实需求有时候需要将多个查询组合到一个查询中去 这时就需要使用集合查询操作了 这个操作类似于数学中的交集,并集,和补集的操作   交集就是返回两个查询共有的记录,关键字是INTERSECT 并集是返回 ...

  9. Java异常与运行时异常,以及与线程的关系

    具体可以看这篇文章:http://www.cnblogs.com/charlesblc/p/6171103.html 都写在里面了,为了避免更新不一致,这里就不再写一遍了.只给个链接. 注意Java和 ...

  10. JavaScript设计模式-单例模式、模块模式(转载 学习中。。。。)

    (转载地址:http://technicolor.iteye.com/blog/1409656) 之前在<JavaScript小特性-面向对象>里面介绍过JavaScript面向对象的特性 ...