程序中事务控制

事务控制概述

编程式事务控制

自己手动控制事务,就叫做编程式事务控制。
Jdbc代码:
Conn.setAutoCommite(false); // 设置手动控制事务
Hibernate代码:
Session.beginTransaction(); // 开启一个事务
【细粒度的事务控制: 可以对指定的方法、指定的方法的某几行添加事务控制】
(比较灵活,但开发起来比较繁琐: 每次都要开启、提交、回滚.)

声明式事务控制

Spring提供了对事务的管理, 这个就叫声明式事务管理。
Spring提供了对事务控制的实现。用户如果想用Spring的声明式事务管理,只需要在配置文件中配置即可; 不想使用时直接移除配置。这个实现了对事务控制的最大程度的解耦。
Spring声明式事务管理,核心实现就是基于Aop。
【粗粒度的事务控制: 只能给整个方法应用事务,不可以对方法的某几行代码应用事务。】
(因为aop拦截的是方法。) Spring声明式事务管理器类:
Jdbc技术:DataSourceTransactionManager
Hibernate技术:HibernateTransactionManager

声明式事务管理

步骤:

1) 引入spring-aop相关的4个jar文件
2) 引入aop名称空间 【XML配置方式需要引入】
3) 引入tx名称空间 【事务方式必须引入】

XML方式实现

1. DeptDao.java
    public class DeptDao {

// 容器注入JdbcTemplate对象
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
} public void save(Dept dept){
String sql = "insert into t_dept (deptName) values(?)";
jdbcTemplate.update(sql,dept.getDeptName());
}
}
2. DeptService
public class DeptService {

// 容器注入dao对象
private DeptDao deptDao;
public void setDeptDao(DeptDao deptDao) {
this.deptDao = deptDao;
} /*
* 事务控制?
*/
public void save(Dept dept){
// 第一次调用
deptDao.save(dept); int i = 1/0; // 异常: 整个Service.save()执行成功的要回滚 // 第二次调用
deptDao.save(dept);
}
}
3. App 测试类
@Test
public void testApp() throws Exception {
//容器对象
ApplicationContext ac = new ClassPathXmlApplicationContext("cn/itcast/a_tx/bean.xml"); // 模拟数据
Dept dept = new Dept();
dept.setDeptName("测试: 开发部"); DeptService deptService = (DeptService) ac.getBean("deptService");
deptService.save(dept); }
4. bean.xml (Spring声明式事务管理配置)
    <?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> <!-- 3. dao实例 -->
<bean id="deptDao" class="cn.itcast.a_tx.DeptDao">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean> <!-- 4. service实例 -->
<bean id="deptService" class="cn.itcast.a_tx.DeptService">
<property name="deptDao" ref="deptDao"></property>
</bean> <!-- #############5. Spring声明式事务管理配置############### -->
<!-- 5.1 配置事务管理器类 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean> <!-- 5.2 配置事务增强(如果管理事务?) -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="find*" read-only="true"/>
<tx:method name="*" read-only="false"/>
</tx:attributes>
</tx:advice> <!-- 5.3 Aop配置: 拦截哪些方法(切入点表表达式) + 应用上面的事务增强配置 -->
<aop:config>
<aop:pointcut expression="execution(* cn.itcast.a_tx.DeptService.*())" id="pt"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/>
</aop:config> </beans>

注解方式实现

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

步骤:
1) 必须引入Aop相关的jar文件
2) bean.xml中指定注解方式实现声明式事务管理以及应用的事务管理器类
3)在需要添加事务控制的地方,写上: @Transactional @Transactional注解:
1)应用事务的注解
2)定义到方法上: 当前方法应用spring的声明式事务
3)定义到类上: 当前类的所有的方法都应用Spring声明式事务管理;
4)定义到父类上: 当执行父类的方法时候应用事务。
Bean.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"
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>
DeptService
@Service
public class DeptService { @Resource
private DeptDao deptDao; /*
* 事务控制?
*/
@Transactional
public void save(Dept dept){
deptDao.save(dept);
int i = 1/0;
deptDao.save(dept);
}
}

事务属性

@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
指定当前的方法必须在事务的环境下执行;
如果当前运行的方法,已经存在事务: 事务会挂起; 会始终开启一个新的事务,执行完后; 刚才挂起的事务才继续运行。

举例:

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

Spring与Hibernate整合

Spring与Hibernate整合关键点:

1) Hibernate的SessionFactory对象交给Spring创建;
2) hibernate事务交给spring的声明式事务管理。

SSH整合:

Spring与Struts;
Spring与hibernate整合;

SH整合步骤:

1)引入jar包
连接池/数据库驱动包
Hibernate相关jar
Spring 核心包(5个)
Spring aop 包(4个)
spring-orm-3.2.5.RELEASE.jar 【spring对hibernate的支持】
spring-tx-3.2.5.RELEASE.jar 【事务相关】
2)配置
hibernate.cfg.xml
bean.xml
3)搭建环境、单独测试

步骤实现

1. DeptDao.java

// 数据访问层
public class DeptDao { // Spring与Hibernate整合: IOC容器注入
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
} // 保存一个记录
// Spring与Hibernate整合:事务管理交给Spring
public void save(Dept dept) {
sessionFactory.getCurrentSession().save(dept);
}
}

2. DeptService

public class DeptService {

private DeptDao deptDao;
public void setDeptDao(DeptDao deptDao) {
this.deptDao = deptDao;
} public void save(Dept dept){
deptDao.save(dept);
}

3. App.java 测试

public class App {

// 容器
private ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); @Test
public void testApp() throws Exception {
DeptService deptServie = (DeptService) ac.getBean("deptService");
System.out.println(deptServie.getClass()); deptServie.save(new Dept());
}
}

4. bean.xml 配置 【Spring管理SessionFactory的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"
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"> <!-- dao 实例 -->
<bean id="deptDao" class="cn.itcast.dao.DeptDao">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean> <!-- service 实例 -->
<bean id="deptService" class="cn.itcast.service.DeptService">
<property name="deptDao" ref="deptDao"></property>
</bean> <!-- 数据源配置 -->
<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> <!-- ###########Spring与Hibernate整合 start########### --> <!-- 方式(1)直接加载hibernate.cfg.xml文件的方式整合
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
</bean> --> <!-- 方式(2)连接池交给spring管理 【一部分配置写到hibernate中,一份分在spring中完成】
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
<property name="dataSource" ref="dataSource"></property>
</bean> --> <!-- 【推荐】方式(3)所有的配置全部都在Spring配置文件中完成 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!-- 注入连接池对象 -->
<property name="dataSource" ref="dataSource"></property> <!-- hibernate常用配置 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property> <!-- hibernate映射配置
<property name="mappingLocations">
<list>
<value>classpath:cn/itcast/entity/*.hbm.xml</value>
</list>
</property>
-->
<property name="mappingDirectoryLocations">
<list>
<value>classpath:cn/itcast/entity/</value>
</list>
</property>
</bean> <!-- ###########Spring与Hibernate整合 end########### --> <!-- 事务配置 -->
<!-- a. 配置事务管理器类 -->
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- b. 配置事务增强(拦截到方法后如果管理事务?) -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="*" read-only="false"/>
</tx:attributes>
</tx:advice>
<!-- c. Aop配置 -->
<aop:config>
<aop:pointcut expression="execution(* cn.itcast.service.*.*(..))" id="pt"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/>
</aop:config> </beans>

java-Spring事务管理、SH整合的更多相关文章

  1. java spring事务管理相关

    一般项目结构为: 数据持久层dao     业务层service     控制层controller 事务控制是在业务层service起作用的,所以需要同时对多张表做添加,修改或删除操作时应该在ser ...

  2. Spring事务管理----------整合学习版

    作者:学无先后 达者为先 Spring提供了一流的事务管理.在Spring中可以支持声明式事务和编程式事务. 一  spring简介 1 Spring的事务       事务管理在应用程序中起着至关重 ...

  3. 【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】

    一.JDBC编程特点 静态代码+动态变量=JDBC编程. 静态代码:比如所有的数据库连接池 都实现了DataSource接口,都实现了Connection接口. 动态变量:用户名.密码.连接的数据库. ...

  4. Spring 事务管理高级应用难点剖析--转

    第 1 部分 http://www.ibm.com/search/csass/search/?q=%E4%BA%8B%E5%8A%A1&sn=dw&lang=zh&cc=CN& ...

  5. Spring事务管理——回滚(rollback-for)控制

    探讨Spring事务控制中,异常触发事务回滚原理.文章进行了6种情况下的Spring事务是否回滚. 以下代码都是基于Spring与Mybatis整合,使用Spring声明式事务配置事务方法. 1.不捕 ...

  6. Spring 事务管理高级应用难点剖析: 第 3 部分

    本文是“Spring 事务管理高级应用难点剖析” 系列文章的第 3 部分,作者将继续深入剖析在实际 Spring 事务管理应用中容易遇见的一些难点,包括在使用 Spring JDBC 时如果直接获取 ...

  7. SSM(spring mvc+spring+mybatis)学习路径——1-2、spring事务管理

    目录 1-2 Spring事务管理 概念介绍 事务回顾 事务的API介绍 Spring 事务管理 转账案例 编程式事务管理 声明式事务管理 使用XML配置声明式事务 基于tx/aop 使用注解配置声明 ...

  8. spring事务管理器设计思想(一)

    在最近做的一个项目里面,涉及到多数据源的操作,比较特殊的是,这多个数据库的表结构完全相同,由于我们使用的ibatis框架作为持久化层,为了防止每一个数据源都配置一套规则,所以重新实现了数据源,根据线程 ...

  9. 事务管理(下) 配置spring事务管理的几种方式(声明式事务)

    配置spring事务管理的几种方式(声明式事务) 概要: Spring对编程式事务的支持与EJB有很大的区别.不像EJB和Java事务API(Java Transaction API, JTA)耦合在 ...

  10. Spring事务管理(转)

    1 初步理解 理解事务之前,先讲一个你日常生活中最常干的事:取钱. 比如你去ATM机取1000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉1000元钱:然后ATM出1000元钱.这两个步骤必须是 ...

随机推荐

  1. restful 服务器一个问题,看ChatGPT的威力

    看看是否牛逼: 真不是写代码的料,也没有这样的天赋,仅仅玩玩而已. 问题:客户端边缘路由中一段js代码,使用get请求一个方法,把json数据送入数据库相关表.由于种种原因导致长连接,通过资源管理器可 ...

  2. idea插件开发踩坑记录

    问题 build.gradles.kts配置文件中全部爆红,提示Cannot access script base class 'org.gradle.kotlin.dsl.KotlinBuildSc ...

  3. 第五届新型功能材料国际会议(ICNFM 2025)

    第五届新型功能材料国际会议(ICNFM 2025) 2025年5月16日-17日 曼谷,泰国 http://www.icnfm.net/ 会议简介 第五届新型功能材料国际会议(ICNFM 2025)将 ...

  4. 事务注解@Transactional

    目录 1.属性介绍 2.传播机制 准备例子 总结 3.原理 4.失效场景 一.属性介绍 1.isolation 属性 事务的隔离级别,默认值为 Isolation.DEFAULT.可选的值有: Iso ...

  5. ConcurrentHashMap(JDK1.8)put分析

    一.ConcurrentHashMap整体结构 ConcurrentHashMap的数据结构与HashMap差不多,都是Node数组+红黑树+链表:ConcurrentHashMap中table的节点 ...

  6. MySQL 的索引下推是什么?

    MySQL 的索引下推是什么? 索引下推(Index Condition Pushdown, ICP)是 MySQL 优化器在 InnoDB 存储引擎中引入的一种查询优化技术,从 MySQL 5.6 ...

  7. 如何使用CSS和JS使网页页面灰掉

    让页面灰掉,通常是通过CSS样式或JavaScript来实现.以下是一些具体的方法: 一.使用CSS样式 应用filter属性 CSS的filter属性可以用来对元素应用图形效果,如灰度.要将整个页面 ...

  8. s2-061(CVE-2020-17530)漏洞复现+利用+getshell工具。

    声明 本文仅用于技术交流,请勿用于非法用途 由于传播.利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任. 文章作者拥有对此文章的修改和解释权.如 ...

  9. js技术之“自定义包含方案”

    调用 // 用于判断包含 function diaoyong(arr, str){ // 初始化 var sizes = ['L','XL','S','M']; for (var i = 0; i & ...

  10. Python基础 - 控制结构

    控制结构: 顺序, 分支, 循环, 理解了, 其实编程就入门一半了. 条件表达式 条件表达式的值只要不是:0 . None. False. 空列表. 空元组. 空集合. 空字典. 空字符串. 空ran ...