Spring 事务管理

来源:互联网 发布:c语言大纲 编辑:程序博客网 时间:2024/06/14 00:13

事务定义:

是一组单一逻辑工作单元的操作集合,要么全部执行,要么不执行。典型的应用是银行转账业务。

事务四大特性:

1. 原子性:事务中全部操作在数据库中是不可分割的,要么全部执行,要么不执行

2. 一致性:几个并行执行的事务,其执行结果必须按某一顺序执行的结果相一致

3. 隔离性: 事务执行不受到其他事务的干扰

4. 持久性:对于事务进行提交后,系统必须保证数据库改变不丢失,即使出现故障

 

注意:事务如果不考虑隔离性,会引发安全问题:脏读、不可重复读、幻读

   脏读:一个事物读取了另一个事务改写的但未提交的数据,如果这些数据被回滚,则读到的数据是无效的

不可重复读: 在同一个事务中,多次读取同一数据返回的结果有所不同

幻读: 一个事物读取几行记录后,另一个事务插入一些记录,幻读就发生了。再后来进行查询,第一个事物就会发现有些原来没有的记录。

 

事物隔离级别

Default : 使用后端数据库默认的隔离级别(Spring中可以进行选择)

Read_uncommited 允许你读取还未提交的改变的数据。导致脏读、幻读、不可重复度

Read_commited 允许在并发事物已经提交后读取。防止脏读,但幻读、不可重复读仍会发生

Repeatable_read 对相同字段多次读取是一致的,除非数据北十五本身改变。可防止脏读、不可重复读,但幻读仍会发生

Serializable 完全服从ACID隔离级别,确保不发生脏、幻、不可重复度。执行效率最慢,它是典型的通过完全锁定在食物中涉及的数据表来完成的。

 

Spring事务传播属性

 Propagation:  key属性确定代理应该给哪个方法增加事务行为。这样的属性最重要的部份是传播行为。有以下选项可供使用:

PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
     
PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。
     PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。
     PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。
     PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
     PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。

Spring中事务管理应用

(一)编程式事务管理(TransactionTempletate

使用TransactionTemplate

 

 

applicationContext.Xml文件中配置事务管理器

//配置事务管理器

<beanid="transactionManager"class="org.springframework.jdbc.datasource.dataSourceTransactionManager ">

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

    </bean>

//配置事务管理模板:Spring为简化事务管理代码提供的类

    <beanid="txTemplate"class="org.springframework.transaction.support.TransactionTemplate">

       <property name="transactionManager"ref="transactionManager"></property>

       <property name="propagationBehaviorName"value="PROPAGATION_REQUIRED"></property//可在这里定义传播行为和隔离级别

    </bean>

 Service 层代码

publicclass Temp1Service {

    private UserDAOuserDAO;

    private DeptDAOdeptDAO;

    TransactionTemplatetxTemplate;

      Get..()/Set..()

     

    publicvoid addTemp(){

       txTemplate.execute(new TransactionCallback(){

           public Object doInTransaction(TransactionStatus status){

              try {

                 User user = new User();

                  Dept dept =new Dept();

                 user.setRemark("USER REMARK");

                 dept.setRemark("DEPT REMARK");

                 userDAO.save(user);

                 deptDAO.save(dept);

              } catch (Exception e) {

                 status.setRollbackOnly();//

                 e.printStackTrace();

                 returnfalse;

              }

              returntrue;

           }

       });

    }

} 

(二)声明式事务管理

1.       声明式事务管理方式一:基于TransactionProxyFactoryBean的方式

这里主要是用到业务层代理

applicationContext.Xml文件中配置

<bean id="transactionManager" 

    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

    <!-- 配置TransactionManager时需要注入数据源引用 -->

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

</bean>

<!-- 下面这个是前面定义的业务Bean -->

<bean id="newsDao" class="com.abc.dao.impl.NewsDaoImpl">

    <!-- 为业务Bean注入属性 -->

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

</bean>

<bean id="newsDaoTransProxy

    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

    <!-- 为事务代理工厂Bean注入事务管理器 -->

    <property name="transactionManager" ref="transactionManager" />

    <!-- 要在哪个Bean上面创建事务代理对象 -->

    <property name="target" ref="newsDao" />

    <!-- 指定事务属性 包括传播行为和隔离级别-->

    <property name="transactionAttributes">

        <props>

            <prop key="*">PROPAGATION_REQUIRED</prop>

        </props>

    </property>

</bean>

 

 

2.       声明式事务管理方式二:基于AspectJXML方式

 

<!-- 切面 -->

<bean id="myAspect" class="net.csdn.www.aop.MyAspect"></bean>

<bean id="userDao" class="net.csdn.www.dao.UserDao"></bean>

 

<!-- 切入点 -->

<aop:config>

           <aop:aspect id="asp1" ref="myAspect">

                    <aop:before method="authority" pointcut="execution(* net.csdn.www.dao.*.*(..))" />

                    <aop:after method="release" pointcut="execution(* net.csdn.www.dao.*.*(..))" />

                    <aop:after-returning method="log"

                             pointcut="execution(* net.csdn.www.dao.*.*(..))" returning="rvt" />

                    <aop:around method="processTx" pointcut="execution(* net.csdn.www.dao.*.*(..))" />

           </aop:aspect>

</aop:config>

 

3.       声明式事务管理方式三:基于注解的方式

 

applicationContext.xml文件中

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
    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-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">


    
<context:annotation-config />
    
<context:component-scan base-package="com.bluesky" />

    
<tx:annotation-driven transaction-manager="transactionManager"/>

    
<bean id="sessionFactory"  
            class
="org.springframework.orm.hibernate3.LocalSessionFactoryBean">  
        
<property name="configLocation" value="classpath:hibernate.cfg.xml" />  
        
<property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
    
</bean>  

    
<!-- 定义事务管理器(声明式的事务) -->  
    
<bean id="transactionManager"
        class
="org.springframework.orm.hibernate3.HibernateTransactionManager">
        
<property name="sessionFactory" ref="sessionFactory" />
    
</bean>


    
此时在DAO上需加上@Transactional注解

@Transactional
@Component("userDao")

public class UserDaoImpl extends HibernateDaoSupport implements UserDao {…..}

 

参考http://www.blogjava.net/robbie/archive/2009/04/05/264003.html
          http://www.blogjava.net/baoyaer/articles/93060.html

0 0
原创粉丝点击