spring 事务支持

一、用4个词来表示事务: 

1: 原子性: 事务是有一个或多个操作组成的一个工作单元。原子性确保事务中的所有操作全部发生或全部部发生。

2: 一致性:一旦事务完成(不管成功和失败),必须确保状态是一致的

3: 隔离性: 事务允许多个用户对相同的数据进行操作,每个用户的操作不会于其他用户关联。因此,事务应该被彼此隔离,避免发生同步读写相同数据的事情

4: 持久性:一但事务完成,事务的结果应该持久话。

二、spring对事务管理的支持(spring 提供了对编码式和声明式事务管理的支持)

1: spring对编码式事务的支持与ejb有很大的区别。ejb与jta 是耦合在一起。而spring编码式事务是通过回调机制将实际的事务实现从事务性的代码中抽像出来。

2: 编码式事务允许用户在代码中精确定义事务的边界,而声明式事务(基于aop)有助于用户将操作与事务规则进行解偶。

 

选择编码式事务还是声明式事务很大程度上是在细粒度控制和易用性之间进行权衡

二、spring并不直接管理事务,提供了多种事务管理器

1: Jdbc 事务

如果在应用程序中你直接使用jdbc来进行持久化,DataSourceTransactionManager 会为你处理事务边界。

<bean id = "transactionManager"               class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

         <property name = "dataSource" ref= "dataSource" > 

 </bean>

2:Hibernate 事务

<bean id="transactionManager" class = "org.springframework.orm.hibernate3.HibernateTransactionManager">

<property name="sessionFactory" ref="sessionFacory">

</bean>

3: java 持久化api事务 :如果你计划采用jpa的话,需要使用spring的jpatransactionmanager

<bean id = "transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">

<property name = "entityManagerFactory" ref=" entityManagerFactory">

</bean> 

JpaTransactionManager 只需要装配一个jpa实体管理工厂。JpaTransactionManager将由工厂所产生的jpa entitymanager合作来构建事务。

除了采用jpa,java 持久化api事务还可以支持jdbc,只是entitymanagerfactory 和 datasource 使用的数据源必须一致。

4:  JTA 事务 : 你的事务需要跨多个事务资源,需要使用Jtatransactionmanager

<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">

<property name = "transactionManagerName" value="java:/TransactionManager"/>

</bean>

 JTA规定了应用程序与一个或多个数据源之间协调事务的标准api

三、spring中的编码式事务:更好地控制事务边界,那么编码式事务是唯一的办法。

添加事务的一种方式是在saveSpittle()方法中直接通过编码使用Spring的TransactionTemplate来添加事务性边界。TransactionTemplate使用了一种回调机制

四、spring中的声明式事务:

通过spring aop框架实现的。因为事务是在应用程序主要功能之上的系统级服务。可以看做是应用程序的切面。声明事务的更好方式是使用Spring的tx命名空间和@Transactional注解

1: 定义事务属性: 声明式事务是通过事务属性来定义的。事务属性描述了事务策略如何应用到方法上。

事务属性包含5个方面:

是否只读,数据库可以利用事务的只读特性来进行一些特定的优化。

事务超时,为了使应用程序很好地运行,事务不能运行太长的时间。

回滚规则,定义那些异常导致事务回滚

隔离级别,定义了一个事务可能受其他并发事务影响的程度。

(1) 脏读 : 一个事务读取了另一个事务改写但尚未提交的数据

(2) 不可重复读: 一个事务执行相同的查询两次,但每次都得不同的数据,原因是另一个并发事务在两次查询期间更新了数据

(3) 幻读:幻读与不可重复读类似。它发生在一个事务读取了几行,另一个并发事务插入一些数据,在随后的查询中,第一个事务就会发现多了一些原本不存在的数据

 传播行为,定义了客户端与被调用方法之间的事务边界。

2: 在xml中定义事务

spring 提供一个tx 命名空间, 其中aop命名空间也应该包括在内。

<tx : advice id = "txAdvice">

<tx : attributes>

     <tx : method name = "save*" propagation = "REQUIRED"/>

     <tx : method name ="*" propagation="SUPPORTS" read-only = "true" />

</tx:attributes>

</tx:advice>

3: 使用注解驱动的事务

<tx : annotation-driven>

@Transactional(propagaton=Propagation.supports,readonly=true)

4: @Transactional 的 propagaton 属性

//事务传播属性

@Transactional(propagation=Propagation.REQUIRED)//如果有事务,那么加入事务,没有的话新创建一个
@Transactional(propagation=Propagation.NOT_SUPPORTED)//这个方法不开启事务
@Transactional(propagation=Propagation.REQUIREDS_NEW)//不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务
@Transactional(propagation=Propagation.MANDATORY)//必须在一个已有的事务中执行,否则抛出异常
@Transactional(propagation=Propagation.NEVER)//不能在一个事务中执行,就是当前必须没有事务,否则抛出异常
@Transactional(propagation=Propagation.SUPPORTS)//其他bean调用这个方法,如果在其他bean中声明了事务,就是用事务。没有声明,就不用事务。
@Transactional(propagation=Propagation.NESTED)//如果一个活动的事务存在,则运行在一个嵌套的事务中,如果没有活动的事务,则按照REQUIRED属性执行,它使用一个单独的事务。这个书屋拥有多个回滚的保存点,内部事务的回滚不会对外部事务造成影响,它只对DataSource TransactionManager事务管理器起效。
@Transactional(propagation=Propagation.REQUIRED,readOnly=true)//只读,不能更新,删除
@Transactional(propagation=Propagation.REQUIRED,timeout=30)//超时30秒

@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.DEFAULT)//数据库隔离级别

 

事务传播行为种类

spring在TransactionDefinition接口中规定了7种类型的事务传播行为,

它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播:

说明

PROPAGATION_REQUIRED

如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。

PROPAGATION_SUPPORTS

支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY

使用当前的事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW

新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED

以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER

以非事务方式执行,如果当前存在事务,则抛出异常。

PROPAGATION_NESTED

如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。 

 

 

http://robinsoncrusoe.iteye.com/blog/825531

猜你喜欢

转载自kayak2015.iteye.com/blog/2293146
今日推荐