spring事务管理

来源:互联网 发布:java properties.load 编辑:程序博客网 时间:2024/06/05 03:39

1.事务管理器和dao的关系

        事务管理是保证数据操作的事务性(原子性、一致性、隔离性、持久性),脱离了事物操作,dao照样可以进行数据操作。

        Spring框架的事务管理器有其独特的优势。Spring框架搜提供的各种好处(AOP、注解MVC等)的前提是让POJO的类变成一个受Spring容器管理的Bean。

        如果我们用一个POJO完成所有的功能,那么这个POJO就即是controller,又是service,还是DAO。

2.重执行日志   

        重执行日志记录了数据库变化的每一个动作。数据库管理系统一般采用重执行日志保证原子性、一致性和持久性。

3.数据并发导致的问题

        三类数据读问题:

        (1)脏读

         A事务读取B事务尚未提交的问题,并对读取的数据操作,如果恰巧B事务回滚,那么A事务的操作是无效的,这就叫做A事务发生了脏读。

       (2)不可重复度

        A事务读取了B事务已经提交的更改数据,导致A两次读取的数据不一致。

       (3)幻想读

        A事务读取B事务提交的新增数据,导致A两次读取数据的不一致。

        两类数据更新问题:

       (1)第一类数据更新

         A事务撤销时,把已经提交的B事务的数据更新覆盖了。

       (2)第二类数据更新:

        A事务覆盖B事务已经提交的数据,造成B事务所作操作丢失。

4.数据库锁机制和数据版本机制

        数据库管理系统采用数据库锁机制保证隔离性,从而解决并发导致的问题。

        多个事物对相同的数据操作,只有持有锁的事物才能操作数据。锁的分类:表锁定、行锁定;共享锁定、独占锁定。

        隔离级别(略)

        Oracle还使用了数据版本的机制,在回滚段为数据的每个变化都保存一个版本,使数据的更改不影响数据的读取。Oracle数据库常用的锁定方式(略)。

4.ThreadLocal

        模板类通过使用ThreadLocal,不使用线程同步,实现线程安全,基本原理是:ThreadLocal类中有一个Map,用于存储线程的变量副本,Map的键是线程对象,Map的值是线程的变量副本。

        ThreadLocal不是一个线程,而是线程的一个本地化对象,工作于多线程中的对象使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程分配一个独立的变量副本。所以每一个线程都可以独立的改变自己的变量副本,不影响其他线程所对应的副本。线程的角度看,这个线程就像是线程的本地变量。

        ThreadLocal接口只有4个方法。

       ThreadLocal的使用方法(举例):

5.Spring事务

        Spring为事务管理提供了事务管理类TransationTemplate和事务回调类TransationCallback.使用这两个类指定具体的持久化操作就可以编程实现事务管理,而无需关注资源获取、复用、事物同步和异常处理的操作。

        Spring采用声明式事务管理,用声明方式在IOC中指定指定事物的边界和事务属性。

        Spring事务管理(SPI)关键抽象层:包括三个接口TransactionDefinition描述事务隔离级别、事务传播规则、事务超时、事务只读等控制事务具体行为的事务属性;PlatformTransactionManager创建事务;TransactionStatus描述这个激活事务的状态。

        Spring将事务管理委托给底层具体的持久化实现框架完成。Spring为不同的持久化框架提供了PlatformTransactionManager。这些框架包括:JPA、JDBC、iBatis、Herbernate3.0。

        资源在同一时刻不能多线程共享,为了让Dao、Service类能够做到Singleton, Spring的事务同步管理器类TransationSynchronizationManager使用ThreadLocal管理为不同事务线程提供了独立的资源副本,同时维护事务配置的属性和运行状态信息。TransationSynchronizationManager将Dao、Service类中影响线程安全的所有“状态”统一抽取到该类中,并用ThreadLocal进行替换。

        Spring框架为不同的持久化技术提供了一套从TransationSynchronizationManager中获取对应线程绑定资源的工具类。


        Spring为不同持久化技术提供了模板类,通过模板类的资源获取工具类间接访问TransationSynchronizationManager中的线程绑定资源,如果Dao使用模板类进行持久化操作,这些Dao就可以配置成Singleton;如果不使用模板类,也可以使用从TransationSynchronizationManager中获取的对应ORM线程绑定资源的工具类。

        当我们调用一个基于Spring的Service接口方法(如UserService#addUser)时,它将运行于Spring的事务管理环境中。

        Service接口方法可能会在内部调用其他的Service接口方法,以共同完成一个业务操作,这就是方法嵌套的情况。Spring通过事务传播行为控制事务如何传播到被嵌套调用的方法中。

使用XML配置(使用tx/aop命令空间)声明式事务:

可以将事务管理代码完全从业务代码中移除。SpringXML配置声明式事务是通过AOP实现的,通过声明,将事务管理逻辑(逻辑如,获取线程绑定资源、开始事务、提交回滚事务、异常转换和处理)动态织入到业务方法相应的连接点中。

<bean id="bbtForum"   class="com.baobaotao.service.impl.BbtForumImpl"   p:forumDao-ref="forumDao"   p:topicDao-ref="topicDao"   p:postDao-ref="postDao"/><!--事务管理器--><bean id="transactionManager"   class="org.springframework.jdbc.datasource.DataSourceTransactionManager"   p:dataSource-ref="dataSource"/><!--使用强大的切点表达式语言轻松定义目标方法--><aop:config><!--通过AOP定义事务增强切面,将service包下所有以Form为后缀的类纳入了需要进行事务增强的范围-->   <aop:pointcut id="serviceMethod"      expression="execution(* com.baobaotao.service.*Forum.*(..))" /><!--引用事务增强-->   <aop:advisor pointcut-ref="serviceMethod"      advice-ref="txAdvice" /></aop:config><!--事务增强--><tx:advice id="txAdvice" ><!--事务属性定义-->       <tx:attributes>            <tx:method name="get*" read-only="false"/>           <tx:method name="add*" rollback-for="PessimisticLockingFailureException"/>           <tx:method name="update*"/>                </tx:attributes>   </tx:advice>

 

使用注解@Transactional配置声明式事务:

注解只是提供元数据,本身不能完成事务切面织入的功能。需要在Spring配置文件对标注@Transactional的Bean进行加工处理,使事务注解生效。

@Transactionalpublic class BbtForumImpl implements BbtForum{ …}

 

<!--由于该Bean被@Transcation标注了,所以将会被注解驱动annotation-driven自动织入事务-->   <bean id="bbtForum"         class="com.baobaotao.service.impl.BbtForumImpl"       p:forumDao-ref="forumDao"       p:topicDao-ref="topicDao"       p:postDao-ref="postDao" />          <bean id="txManager"      class="org.springframework.jdbc.datasource.DataSourceTransactionManager"      p:dataSource-ref="dataSource"/>   <!--对标注@transcation注解的bean进行加工处理,以织入事务管理切面-->   <tx:annotation-driven transaction-manager="txManager" proxy-target-class="true" /></beans>







原创粉丝点击