7.spring的事务管理

来源:互联网 发布:淘宝鞋子质量问题范围 编辑:程序博客网 时间:2024/05/22 14:39
1.数据库事务基础知识
  1.1 数据库事务的4个特性:原子性,一致性,隔离性,持久性。简称ACID,数据“一致性”是最终目标。
  1.2 数据并发问题: 数据读取问题(脏读、不可重复读、幻象读),数据库更新问题(第一类丢失更新、第二类丢失更新)书P291
        脏读:A事务读取B事务尚未提交的更改数据,并在这个数据的基础上操作
        不可重复读:A事务读取了B事务已经提交的更改数据
        幻象读:A事务读取B事务提交提交的新增数据
        第一类丢失更新:A事务撤销时,把已经提交的B事务的更新数据覆盖了
        第二类丢失更新:A事务提交时覆盖B事务已经提交的数据
  1.3 数据库锁机制
       按锁定对象不同,可分为表锁定和行锁定;从并发事务锁定的关系上看,可分为共享锁定和独占锁定
  1.4 事务隔离级别(书P294)
       ANSI/ISO 92标准定义了4个等级的事务隔离级别。
                                                                                            事务隔离级别对并发问题的解决情况:

隔离级别
脏读
不可重复读
幻象读
第一类丢失更新
第二类丢失更新
(未提交读)
READ UNCOMMITED
×
已提交读
READ COMMITED
×
×
可重复读
REPEATABLE READ
×
×
×
×
串行化
SERIALIZABLE
×
×
×
×
×

  1.5 JDBC对事务支持
        并不是所有的数据库都支持事务,即使支持事务的数据库也并非支持所有的事务隔离级别。可通过Connection的对象的方法查看底层数据库的事务支持情况。
        Connection默认情况下是自动提交的,即每条执行的SQL都对应一个事务。事务最终操作有:提交与回滚(回滚到事务开始处或者或者保存点处)

2.ThreadLocal基础知识
   2.1 概念:ThreadLocal是线程的一个本地化对象。ThreadLocal为每个使用该变量的线程分配一个独立的变量副本。支持泛型,为ThreadLocal<T>
   2.2 接口方法: set、get、remove、initialValue
   2.3 与Thread同步机制的比较:ThreadLocal采用了“以空间换时间”的方式:访问并行化,对象独享化
   2.4 Spring使用ThreadLocal解决线程安全问题

3.Spring对事务管理的支持
   3.1 Spring为事务管理提供了一致的编程模板,在高层次建立了统一的事务抽象。也就是说,不管使用SpringJDBC、Hibernate、JPA还是iBatis,Spring都让我们可以用统一的编程模型进行事务管理。Spring事务管理的亮点在于声明式事务管理。Spring允许通过声明方式,在IoC配置中指定事务的边界和事务属性,Sping自动在指定边界上应用事务属性。
   3.2 事务管理关键抽象:Spring在事务管理高层抽象层主要包括3个接口,分别是 PlatformTransactionManaget、TransactionDefinition和TransactionStatus.
         TransactionDefinition定义了Spring兼容的事务属性,如下:
         事务隔离:当前事务和其他事务的隔离程度。4个隔离级别:ISOLATION_READ_UNCOMMITED 、ISOLATION_READ_COMMITED 、ISOLATION_REPEATABLE_READ 、ISOLATION_SERIALIZABLE,此外,还定义了一个默认的隔离级别:ISOLATION_DEFAULT,它表示使用底层数据库的默认隔离级别( MySQL默认是可重复读,Oracle、SQLServer、DB2等默认是已提交读 )。
        事务传播:通常在一个事务中执行的所以代码都会运行于同一事务上下文中。但是Spring也提供了几个可选的事务传播类型,见下文描述。
        事务超时:事务在超时前能运行多久,超过时间后,事务被回滚。
        只读状态:只读事务不修改任何数据。试图在只读事务中更改数据将引发异常。
        Spring运行通过XML或注解元数据的方式为一个有事务要求的服务类方法配置事务属性。
   3.3 Spring事务管理器实现类
         Spring将事务管理委托给底层具体的持久化实现框架完成。不同持久化技术对应不同的事务管理器实现类:(书P305)。
事务实现类
说明
 org.springframework.orm.jpa.JpaTransactionManager
使用JPA进行持久化时,使用该事务管理器
org.springframework.orm.hibernate3.HibernateTransactionManager
使用Hibernate3.0版本进行持久化时,使用该事务管理器
org.springframework.jdbc.datasource.DataSourceTransactionManager
使用Spring JDBC或iBatis等基于DataSource数据源的持久化技术时,使用该事务管理器
org.springframework.orm.jdo.JdoTransactionManager
使用JDO进行持久化时,使用该事务管理器
org.springframework.transaction.jta.JtaTransactionManager
具有多个数据源的全局事务使用该事务管理器(不管采用何种持久化技术),如果希望在Java EE容器里使用JTA,我们将通过JNDI和Spring的JtaTransactionManager获取一个容器管理的DataSource。
  
   3.4事务传播行为:Spring通过事务传播行为控制当前的事务如何传播到嵌套调用的目标服务接口方法中。
       Spring在TransactionDefinition接口中规定了7种类型的事务传播行为,如下:

事务传播行为类型
说明
PROPAGATION_REQUIRED
如果当前没有事务,就新建一个事务,如果已经存在一个事务,加入到这个事务中。这是最常见的选择。
PROPAGATION_SUPPORTS
支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY
使用当前的事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW
新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER
以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。


4.使用xml配置声明式事务
   4.1 使用原始的TransactionProxyFactoryBean(书P313)
   4.2 基于tx/aop命名空间的配置(书P315):利用动态代理、使用事务增强(切点表达式)
         <tx:method>元素属性表:见书P318

5.使用注解配置声明式事务
    5.1 使用@Transactional注解 (书P318)
         spring配置文件的注解解析处理:<tx:annotation-driven transaction-manager="xxx">,还有两个属性:proxy-target-class:为true则spring通过子类代理,为false则使用基于接口的代理;order属性
         使用基于@Transactional注解的配置和基于XML的配置方式一样,它拥有一组普适性很强的默认事务属性,我们往往可以直接使用这些默认的属性就可以了,默认值如下:
         
事务传播行为
PROPAGATION_REQUIRED
事务隔离级别
SOLATION_DEFAULT,表示采用数据库本身的隔离级别
读写事务属性
读写事务
超时时间
依赖于底层的事务系统的默认值
回滚设置
任何运行期异常引发回滚(unchecked),任何检查型异常不会引发回滚

  @Transactional注解属性说明:

propagation
事务传播行为,通过以下枚举类提供合法值:org.springframework.transaction.annotation.Propagation,例如:@Transactional(propagation=Propagation.REQUIRES_NEW)
isolation
事务隔离级别,通过以下枚举类提供合法值:org.springframework.transaction.annotation.Isolation,例如:@Transactional(isolation=Isolation.READ_COMMITTED)
readOnly
事务读写性,boolean型,例如:@Transactional(readOnly=true)
timeout
超时时间,int型,秒为单位,例如:@Transactional(timeout=10)
rollbackFor
一组异常类,遇到时进行回滚,类型为:Class<? Extends Throwable>[],默认为{}。例如:@Transactional(rollbackFor={SQLException.class}),多个异常之间可用逗号分隔。
rollbackForClassName
一组异常类名,遇到时进行回滚,类型为String[],默认值为{}。例如:@Transactional(rollbackForClassName={Exception"})
noRollbackFor
和rollbackFor相对。
noRollbackForClassName
和rollbackForClassName相对。

    如果使用子类代理,在接口标注了@Transactional注解,其实现类依旧不会启用事务机制。所以,Spring建议在具体业务类上使用@Transactional注解。这样,不管<tx:annotation>将proxy-target-class属性配置为true或false,业务类都会启用事务机制。
   在方法处的注解会覆盖类定义处的注解。

原创粉丝点击