zoukankan      html  css  js  c++  java
  • SSM框架——以注解形式实现事务管理

    SSM框架——以注解形式实现事务管理 

    上一篇博文《SSM三大框架整合详细教程》详细说了如何整合Spring、SpringMVC和MyBatis这三大框架。但是没有说到如何配置mybatis的事务管理,实现开发中,事务是必不可少的。本篇作为对上一篇的补充,说明在SSM框架中如何使用注解的形式进行事务管理。

    什么是事务?

              在编写业务的过程中,会需要进行事务处理,当需要执行多条插入语句时,如果前几条成功,而最后一条失败,那么我们需要回滚数据库操作,保持数据的一致性和完整性,此时,就需要利用DB的事务处理。事务是恢复和并发控制的基本单位。


            简单来说,所谓的事务,是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。


    事务应该具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性。


           原子性(atomicity)。一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。


           一致性(consistency)。事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。


           隔离性(isolation)。一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。


           持久性(durability)。持续性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。

    MyBatis集成Spring事务管理

               在SSM框架中,使用的是Spring的事务管理机制。Spring可以使用编程式实现事务,声明式实现事务以及注解式实现事务。本文主要说一下如何使用注解式@Transanctional实现实现事务管理。

    本文代码例子基于上一篇博文,具体代码《SSM三大框架整合详细教程》中已经给出。简单看下目录结构以及实体类:

    1、配置spring-mybatis.xml文件

           

             如要实现注解形式的事务管理,只需要在配置文件中加入以下代码即可:

    1. <!-- 开启事务注解驱动 -->  
    2.     <tx:annotation-driven />  
    3.     <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->  
    4.     <bean id="transactionManager"  
    5.         class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
    6.         <property name="dataSource" ref="dataSource" />  
    7.     </bean>  

               

                当然,如果此时xml文件报错,那是由于没有引入xmlns和schema导致的,无法识别文档结构。引入头文件即可,以下是我的,根据自己需要引入:

    1. <beans xmlns="http://www.springframework.org/schema/beans"  
    2.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"  
    3.     xmlns:context="http://www.springframework.org/schema/context"  
    4.     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc"  
    5.     xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
    6.     xsi:schemaLocation="http://www.springframework.org/schema/beans    
    7.                         http://www.springframework.org/schema/beans/spring-beans-3.1.xsd    
    8.                         http://www.springframework.org/schema/context    
    9.                         http://www.springframework.org/schema/context/spring-context-3.1.xsd  
    10.                         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd    
    11.                         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd    
    12.                         http://www.springframework.org/schema/mvc    
    13.                         http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">  

    2、如何使用

              在此用一个小例子来测试事务管理是否成功配置。代码基础是SSM框架搭建里面的测试代码。我们现在测试的方法是:我要插入一个User对象的集合,如果此对象数量小于2,那么可以成功插入,但是如果大于2,那么就抛出异常(事务处理必须抛出异常,只有这样Spring才帮助事务回滚),这样数据库就会回滚,不插入任何数据。测试结果如果数据库没插入任何数据,那么表示事务处理配置成功,反正,失败。

         注意@Transactional只能被应用到public方法上,对于其它非public的方法,如果标记了@Transactional也不会报错,但方法没有事务功能。 

            实体类、DAO接口,业务接口,以及业务实现都有,这个测试仅需要在业务层中添加一个方法,然后使用JUnit测试即可,业务实现类中添加如下方法,注意注解@Transactional:

    1. /** 
    2.      * 事务处理必须抛出异常,Spring才会帮助事务回滚 
    3.      * @param users 
    4.      */  
    5.       
    6.     @Transactional  
    7.     @Override  
    8.     public void insertUser(List<User> users) {  
    9.         // TODO Auto-generated method stub  
    10.         for (int i = 0; i < users.size(); i++) {  
    11.             if(i<2){  
    12.                 this.userDao.insert(users.get(i));  
    13.             }  
    14.             else {  
    15.                 throw new RuntimeException();  
    16.             }  
    17.         }  
    18.     }  

    接下来在测试类中添加如下方法进行测试:
    1. @Test  
    2.     public void testTransaction(){  
    3.         List<User> users = new ArrayList<User>();  
    4.         for(int i=1;i<5;i++){  
    5.             User user = new User();  
    6.             user.setAge(i);  
    7.             user.setPassword(i+"111111");  
    8.             user.setUserName("测试"+i);  
    9.             users.add(user);  
    10.         }  
    11.         this.userService.insertUser(users);  
    12.     }  


             注意:此时进行JUnit测试会发现出现错误,这是因为方法中抛出了这个异常。实质上确实进行了事务管理,数据没有插入,此时表示配置成功了;反之,如果去掉注解,那么前两条数据会插入成功,然后后面会抛出异常。

  • 相关阅读:
    $.contains(a,b)
    文件拷贝, 使用 BIO,NIO的对比,四种写法性能分析。
    win32 窗口缩放时出现闪屏
    Java: md5 加密中文 & 注意编码
    win32: 查询滚动条相关信息的注意事项
    查询字符串(性能对比): Array Vs HashMap
    多线程读取,单线程写入
    写入与读取第三方的 cookie
    asp 读cookie 下划线 丢失
    win7(旗舰版)下,OleLoadPicture 加载内存中的图片(MagickGetImageBlob),返回值 < 0
  • 原文地址:https://www.cnblogs.com/aoshicangqiong/p/7657051.html
Copyright © 2011-2022 走看看