Spring学习笔记(十七)----Spring中的事务

事务就是一组数据库操作,但这组操作是具有原子性的(atomic)。所谓原子操作,即这组数据库操作要么就都执行成功,要么就一个也没执行。当有一些操作成功了(“成功”指数据库里的数据已更新或提交),但中间出现异常,后边的也就无法执行时,事务要回滚,即恢复到什么也没执行以前的状态。

举个比较常见的例子,一位顾客要进行银行转帐,把100元从A帐户转到B帐户,一般的过程是把A帐户的总额减去100,B帐户的总额加上100(只考虑最简单情况)。当在A帐户总额减去100后出现异常情况,使得无法再对B帐户进行操作。如果没使用事务,那么这位顾客就损失了100元,但如果使用了事务,那么出现异常后,事务回滚,使得A帐户总额恢复到减去100以前的金额。虽然使用事务并没有达到顾客转帐的目的,但避免了出现异常情况时顾客的损失。

事务就相当于我们做一件事情(这件事由许多小的步骤组成),要么我们就把这件事情完完整整地做成功,要么我们就一点也不要做。不能做到半截撂摊子不干了。

回到Spring来,Spring的Dao框架对事务提供了强大的支持。它包括有两种事物管理,即:

  • 编程式事物管理(programmatic tansaction management)
  • 声明式事物管理(Declarative tansaction management)

所谓编程式事物管理,就是把事物管理以代码的形式编写到你的应用中要使用事物管理的地方,灵活性较强。而声明式事物管理是以配置文件的形式在xml文件中定义,好处是不具有代码入侵性,当不需要事物管理时,可以直接修改配置文件,而不用修改代码。以后会介绍这两种事物管理。

在Spring中,主要涉及以下几种事物属性:

1. 传播行为(propagation behavior)

它是对事物的起始,暂停,终止时刻的定义,主要有以下几种

 参数  含义
 PROPAGATION_REQUIRED  如果存在事物的话,就继续这个事物,如果不存在,新建一个事物。
 PROPAGATION_SUPPORTS  如果存在事物的话,就继续这个事物,如果不存在,就以非事务的方式进行。
 PROPAGATION_MANDATORY  必须在现存事物中执行,否则抛出异常。
 PROPAGATION_REQUIRES_NEW  建立一个新事物,如果现存一个事物,则暂停它。
 PROPAGATION_NOT_SUPPORTED  不再事务中执行,如果现存事物,则暂停它。
 PROPAGATION_NEVER  不再事务中执行,如果现存事物,则抛出异常。
 PROPAGATION_NESTED  在一个嵌入的事物中执行,否则同PROPAGATION_REQUIRED

上述参数是在org.springframework.transaction.TransactionDefinition接口中定义的(类型是public static final,值从0到6)。上述参数中最常用的是PROPAGATION_REQUIRED

2. 隔离等级(isolation level)

在一个应用应用程序中,可能有多个事务在运行,这时就会产生一些问题。

  • dirty read

一个事物更新了数据库中的某些数据,另一个事物读取了这些数据,这时前一个事物由于某些原因回滚了,那么第二个事物读取的数据就是“脏数据”。

  • non-repeatable read

一个事物需要两次查询同一数据,但两次查询中间可能有另外一个事物更改了这个数据,导致前一个事物两次读出的数据不一致。

  • phantom read

一个事物两次查询同一个表,但两次查询中间可能有另外一个事物又向这个表中插入了一些新数据,导致前一个事物的两次查询不一致。

为了解决以上问题,Spring的事物管理定义了一些隔离级别,所谓“隔离”,即对数据的锁定。

 参数  含义
 ISOLATION_DEFAULT  使用数据库默认的隔离级别
 ISOLATION_READ_UNCOMMITTED  容许事物读取其他并行事物还未提交的数据。这种级别会出现上面三种情况。
 ISOLATION_READ_COMMITTED  容许事物读取其他并行事物已经提交(commit)的数据,可防止dirty read
 ISOLATION_REPEATABLE_READ
这种级别会可以防止上面三种情况发生。

 ISOLATION_SERIALIZABLE  使用事物锁,锁定相应数据,可以防止上面三种情况发生,但效率比较低。

上述参数也是在org.springframework.transaction.TransactionDefinition接口中定义的(类型是public static final,值为-1,1,2,4,8)。上述参数中最常用的是ISOLATION_DEFAULT

3. read only

应用这项属性时,底层的数据库可以对读取进行最优化,但要配合PROPAGATION_REQUIRED,PROPAGATION_REQUIRES_NEW或PROPAGATION_NESTED使用,即只能在事物中使用。

4. timeout

在多事物并行情况下,为了保证正确性,有些事物的操作会有延迟,甚至死锁。设置事物超时时间,可以避免事物的长时间等待。设置事物超时时间也要配合PROPAGATION_REQUIRED,PROPAGATION_REQUIRES_NEW或PROPAGATION_NESTED使用。

以上的四种属性及其相应方法都定义在org.springframework.transaction.TransactionDefinition接口及其实现类(如org.springframework.transaction.support.DefaultTransactionDefinition)里。

时间: 2024-08-27 02:24:31

Spring学习笔记(十七)----Spring中的事务的相关文章

spring学习笔记(一) Spring概述

博主Spring学习笔记整理大部分内容来自Spring实战(第四版)这本书.  强烈建议新手购入或者需要电子书的留言. 在学习Spring之前,我们要了解这么几个问题:什么是Spring?Spring的优势在哪里?怎么系统的学习Spring? 一.什么是Spring? Spring是一个开源的轻量级Java SE(Java 标准版本)/Java EE(Java 企业版本)开发应用框架,其目的是用于简化企业级应用程序开发. 那有人就会问了,Spring是如何简化开发的? 在传统开发中,一个应用是需

spring学习笔记:spring事务管理 (转)

关于事物隔离级别, 脏读, 不可重复读, 幻读的理解, 另有一篇文章比较生动的介绍:http://blog.csdn.net/sunxing007/article/details/6427290 spring事务管理相关的接口: TransactionDefinition:代表一个事物,描述了事务的隔离级别, 超时时间,事务是否只读, 传播规则等等; TransactionStatus:描述事物的状态; PlatformTransactionManager:事务管理器接口, 只定义了3个方法:g

Spring学习笔记——关于Spring注解扫描不能注入new对象问题

这几天Leader让我用工厂模式对部分业务逻辑代码进行重构,过程是痛苦的(这里就不详细说了),结果很甜蜜.下面记录一下我在重构过程中遇到一个问题. 部分代码如下: @service(orderFactory) public class OrderFactory implements IOrderFactory{ public OrderCreate factory(String type){ if(type != null && type.indexOf("1")! =

Spring学习笔记之五----Spring MVC

Spring MVC通常的执行流程是:当一个Web请求被发送给Spring MVC Application,Dispatcher Servlet接收到这个请求,通过HandlerMapping找到Controller,将这个请求委派给Controller的某个Handler Method处理,这个Handler Method处理完这个请求,返回一个ModelAndView给Dispatcher Servlet,Dispatcher Servlet利用View Name,请求View Resolv

Spring学习笔记--在SpEL中筛选集合

要用到Spring的util(包括util:list等),xml文件中的beans中需要添加一些有关util的信息: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance&q

Spring学习笔记1——spring搭建

1.新建一个java工程 2.添加spring相关的jar包并添加到引用 3.添加spring依赖的相关jar包并添加到引用 4.编写spring配置文件applicationcontext.xml 新建applicationContext.xml文件,然后编写头文件.关于spring头文件的写法可以参考spring提供的guide. 解压下载的spring文件,找到docs\spring-framework-reference\html\index.html并打开,然后找到 在打开的页面中会有

Spring学习笔记--使用Spring基于Java的配置

我们需要使用@Component注解来定义一个配置类,在配置类中我们定义Bean: package com.moonlit.myspring; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MoonlitConfig { @Bean public Weapon h

不错的Spring学习笔记(转)

Spring学习笔记(1)----简单的实例 ---------------------------------   首先需要准备Spring包,可从官方网站上下载.   下载解压后,必须的两个包是spring.jar和commons-logging.jar.此外为了便于测试加入了JUnit包.   在Myeclipse中创建Java项目.   编写一个接口类,为了简单,只加入了一个方法.   Java代码   1.package com.szy.spring.interfacebean;  

《Spring学习笔记》:Spring、Hibernate、struts2的整合(以例子来慢慢讲解,篇幅较长)

<Spring学习笔记>:Spring.Hibernate.struts2的整合(以例子来慢慢讲解,篇幅较长) 最近在看马士兵老师的关于Spring方面的视频,讲解的挺好的,到了Spring.Hibernate.struts2整合这里,由于是以例子的形式来对Spring+Hibernate+struts2这3大框架进行整合,因此,自己还跟着写代码的过程中,发现还是遇到了很多问题,因此,就记录下. 特此说明:本篇博文完全参考于马士兵老师的<Spring视频教程>. 本篇博文均以如下这

Spring学习笔记一(Spring核心思想)

通过学习<Spring in action (Third edition)>的第一章,我大概了解了Spring的基本思想: 1,依赖注入(Dependnecy Injection): 在不使用Spring框架的情况下,一个类要跟另一个类建立联系,可能会使用如下的模式: class A{...} class B{ private A a; ...       } 这样的话,每次实例化一个B的对象,如b1,必定实例化一个A的对象,如a1,并且b1和a1是紧耦合的,b1牢牢地和a1绑定在一起了.他们