spring aop 声明式事务管理

Spring使用AOP来完成声明式的事务管理   有annotation和xml两种形式

代码和上一篇基本相近,再贴一遍

两个实体类

package com.ouc.wkp.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity(name = "t_log")
public class Log {
    private int id;
    private String msg;

    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

}

Log.java

package com.ouc.wkp.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity(name="user2")
public class User2 {
    private int id;
    private String username;

    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Column
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

}

User2.java

两个接口DAO

package com.ouc.wkp.dao;

import com.ouc.wkp.model.Log;

public interface LogDAO {
    public void save(Log log);
}

LogDAO.java

package com.ouc.wkp.dao;

import com.ouc.wkp.model.User2;

public interface UserDAO {
    public void save(User2 user2);
    public void delete();
}

UserDAO.java

接口实现

package com.ouc.wkp.dao.impl;

import java.sql.Connection;
import java.sql.SQLException;

import javax.annotation.Resource;
import javax.sql.DataSource;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Component;

import com.ouc.wkp.dao.UserDAO;
import com.ouc.wkp.model.User2;

@Component("u")
public class UserDAOImpl implements UserDAO {

    // private DataSource dataSource;
    //
    // public DataSource getDataSource() {
    // return dataSource;
    // }
    //
    // @Resource
    // public void setDataSource(DataSource dataSource) {
    // this.dataSource = dataSource;
    // }

    private SessionFactory sessionFactory;

    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    @Resource
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Override
    public void save(User2 user2) {
        // Hibernate
        // JDBC
        // XML
        // NetWork
//        System.out
//                .println("session factory class:" + sessionFactory.getClass());
        Session s = sessionFactory.getCurrentSession();
//        s.beginTransaction();
        s.save(user2);
//        s.getTransaction().commit();
//        System.out.println("user saved!");

    }

    @Override
    public void delete() {
        // TODO Auto-generated method stub

    }

}

UserDAOImpl.java

package com.ouc.wkp.dao.impl;

import javax.annotation.Resource;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Component;

import com.ouc.wkp.dao.LogDAO;
import com.ouc.wkp.model.Log;

@Component("logDAO")
public class LogDAOImpl implements LogDAO {

    private SessionFactory sessionFactory;

    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    @Resource
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Override
    public void save(Log log) {
        Session s = sessionFactory.getCurrentSession();
        s.save(log);
//        throw new RuntimeException();//事务会回滚   spring配置后省去了try catch
    }

}

LogDAOImpl.java

package com.ouc.wkp.service;

import javax.annotation.Resource;

import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.ouc.wkp.dao.LogDAO;
import com.ouc.wkp.dao.UserDAO;
import com.ouc.wkp.model.Log;
import com.ouc.wkp.model.User2;

@Component("userService")
public class UserService {

    private UserDAO userDAO;
    private LogDAO logDAO;

    public LogDAO getLogDAO() {
        return logDAO;
    }

    @Resource(name = "logDAO")
    public void setLogDAO(LogDAO logDAO) {
        this.logDAO = logDAO;
    }

    public User2 getUser(int id) {
        return null;
    }

    public void init() {
        System.out.println("init");
    }

//    @Transactional(propagation = Propagation.REQUIRED)
    // 事务的传播特性 默认REQUIRED
    // readOnly=true只读的 spring会进行优化
    // 声明式事务管理 进行事务
    public void add(User2 user2) {
        userDAO.save(user2);
        Log log = new Log();
        log.setMsg("a user saved");
        logDAO.save(log);
    }

    public UserDAO getUserDAO() {
        return userDAO;
    }

    @Resource(name = "u")
    public void setUserDAO(UserDAO userDAO) {
        this.userDAO = userDAO;
    }

    public void destroy() {
        System.out.println("destroy");
    }
}

UserService.java

使用注解时在对应的方法前加上@Transactional(propagation = Propagation.REQUIRED)

(propagation = Propagation.REQUIRED)可以省去,因为事务的传播特性 默认为REQUIRED

配置文件

  1 <?xml version="1.0" encoding="UTF-8"?>
  2 <beans xmlns="http://www.springframework.org/schema/beans"
  3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
  4     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
  5     xsi:schemaLocation="http://www.springframework.org/schema/beans
  6             http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
  7             http://www.springframework.org/schema/context
  8             http://www.springframework.org/schema/context/spring-context-3.1.xsd
  9             http://www.springframework.org/schema/aop
 10             http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
 11             http://www.springframework.org/schema/tx
 12            http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
 13     <context:annotation-config />
 14     <!-- 使用注解需要下面四条 -->
 15     <!-- xmlns:context="http://www.springframework.org/schema/context" -->
 16     <!-- http://www.springframework.org/schema/context -->
 17     <!-- http://www.springframework.org/schema/context/spring-context-3.1.xsd"> -->
 18     <!-- <context:annotation-config /> -->
 19
 20     <!-- 使用aop需要一下 -->
 21     <!-- xmlns:aop="http://www.springframework.org/schema/aop" -->
 22     <!-- http://www.springframework.org/schema/aop -->
 23     <!-- http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> -->
 24     <!-- <aop:aspectj-autoproxy /> -->
 25
 26     <!-- 使用事务 -->
 27     <!-- xmlns:tx="http://www.springframework.org/schema/tx" -->
 28     <!-- http://www.springframework.org/schema/tx -->
 29     <!-- http://www.springframework.org/schema/tx/spring-tx-2.5.xsd -->
 30     <!-- <tx:annotation-driven transaction-manager="txManager"/> -->
 31
 32
 33     <!-- 扫描 -->
 34     <context:component-scan base-package="com.ouc.wkp"></context:component-scan>
 35
 36     <aop:aspectj-autoproxy />
 37
 38     <bean
 39         class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
 40         <property name="locations">
 41             <value>classpath:jdbc.properties</value>
 42         </property>
 43     </bean>
 44
 45     <bean id="dataSource" destroy-method="close"
 46         class="org.apache.commons.dbcp.BasicDataSource">
 47         <property name="driverClassName" value="${jdbc.driverClassName}" />
 48         <property name="url" value="${jdbc.url}" />
 49         <property name="username" value="${jdbc.username}" />
 50         <property name="password" value="${jdbc.password}" />
 51     </bean>
 52
 53     <bean id="sessionFactory"
 54         class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
 55         <property name="dataSource" ref="dataSource" />
 56         <!-- <property name="annotatedClasses"> -->
 57         <!-- <list> -->
 58         <!-- <value>com.ouc.wkp.model.User2</value> -->
 59         <!-- <value>com.ouc.wkp.model.Log</value> -->
 60         <!-- </list> -->
 61         <!-- </property> -->
 62         <property name="packagesToScan">
 63             <list>
 64                 <value>com.ouc.wkp.model</value>
 65             </list>
 66         </property>
 67         <property name="hibernateProperties">
 68             <props>
 69                 <prop key="hibernate.dialect">
 70                     org.hibernate.dialect.MySQLDialect
 71                 </prop>
 72                 <prop key="hibernate.show_sql">true</prop>
 73             </props>
 74         </property>
 75     </bean>
 76
 77
 78     <!-- Spring使用AOP来完成声明式的事务管理 -->
 79     <bean id="txManager"
 80         class="org.springframework.orm.hibernate4.HibernateTransactionManager">
 81         <!-- <property name="dataSource" ref="dataSource" /> -->
 82         <property name="sessionFactory" ref="sessionFactory" />
 83     </bean>
 84
 85     <tx:annotation-driven transaction-manager="txManager" />
 86
 87     <aop:config>
 88         <aop:pointcut expression="execution(public * com.ouc.wkp.service..*.*(..))"
 89             id="businessService" />
 90         <!-- 在此pointcut上加上txAdvice建议 -->
 91         <aop:advisor advice-ref="txAdvice" pointcut-ref="businessService" />
 92     </aop:config>
 93
 94     <tx:advice id="txAdvice" transaction-manager="txManager">
 95         <tx:attributes>
 96             <tx:method name="getUser" read-only="true" />
 97             <tx:method name="add*" propagation="REQUIRED" />
 98         </tx:attributes>
 99     </tx:advice>
100
101 </beans>

beans.xml

两个地方需要注意

1.这种方式可以省去写多个model类的配置

<property name="packagesToScan">
  <list>
    <value>com.ouc.wkp.model</value>
  </list>
</property>

2.

bean定义了一个事务管理,注入sessionFactory。

紧接着规定事务管理器为txManager即上面bean中定义的。

<aop:config>定义一个切面,在这个切面加上advice。

最后定义一个advice,

<tx:method name="getUser" read-only="true" />表示getUser方法是只读的并且进行了声明式事务管理。readonly可以提高程序效率。

<tx:method name="add*" propagation="REQUIRED" />标识为以add开头的方法添加事务。

测试类

package com.ouc.wkp.test;

import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.ouc.wkp.model.User2;
import com.ouc.wkp.service.UserService;

//Dependency Injection
//Inverse of Control
public class UserServiceTest {

    @Test
    public void testAdd() throws Exception {
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
                "beans.xml");

        UserService service = (UserService) ctx.getBean("userService");
        User2 user2=new User2();
        user2.setId(1);
        user2.setUsername("ttyy");
        System.out.println(user2);
        service.add(user2);

        ctx.destroy();

    }

}

UserServiceTest.java

如果出错则事务回滚,两条记录都增加失败。

时间: 2024-08-03 07:14:31

spring aop 声明式事务管理的相关文章

spring mvc + mybatis + spring aop声明式事务管理没有作用

在最近的一个项目中,采用springMVC.mybatis,发现一个很恼人的问题:事务管理不起作用!!网上查阅了大量的资料,尝试了各种解决办法,亦未能解决问题! spring版本:3.0.5 mybatis版本:3.2.2 1.applicationContext.xml配置: mvc + mybatis + spring aop声明式事务管理没有作用" title="spring mvc + mybatis + spring aop声明式事务管理没有作用">2.spr

Spring AOP声明式事务的缺陷

Spring AOP声明式事务的缺陷 今天项目验收时遇到的一个问题,记录一下 转载:http://liuu.iteye.com/blog/422810 [问题]        Spring的声明式事务,我想就不用多介绍了吧,一句话“自从用了Spring AOP啊,事务管理真轻松啊,真轻松:事务管理代码没有了,脑不酸了,手不痛了,一口气全配上了事务:轻量级,测试起来也简单,嘿!”.不管从哪个角度看,轻量级声明式事务都是一件解放生产力的大好事.所以,我们“一直用它”. 不过,最近的一个项目里,却碰到

Spring学习之Spring的声明式事务管理详解

声明式事务管理 大多数Spring用户选择声明式事务管理的原因是,这个是对应用代码影响最小的选择,因此也最符合 非侵入式 轻量级容器的理念. Spring声明式事务管理可以在任何环境下使用.只需更改配置文件, 它就可以和JDBC.JDO.Hibernate或其他的事务机制一起工作. Spring的声明式事务管理可以被应用到任何类(以及那个类的实例)上. Spring提供了声明式的回滚规则. Spring允许你通过AOP定制事务行为.(例如,如果需要,你可以在事务回滚中插入定制的行为. 你也可以增

转 Spring @Transactional 声明式事务管理 getCurrentSession

Spring @Transactional声明式事务管理  getCurrentSession   在Spring @Transactional声明式事务管理的配置中,hibernate.current_session_context_class=thread- 这一句是不能加的-加了就会出错..那为什么不能加呢? 那是因为在Spring事务管理中,current Session是绑定到SpringSessionContext中的,而不是ThreadLocalSessionContext中的 先

Spring的声明式事务管理&lt;tx:advice/&gt; 有关的设置

<tx:advice/> 有关的设置 这一节里将描述通过 <tx:advice/> 标签来指定不同的事务性设置.默认的 <tx:advice/> 设置如下: 事务传播设置是 REQUIRED 隔离级别是 DEFAULT 事务是 读/写 事务超时默认是依赖于事务系统的,或者事务超时没有被支持. 任何 RuntimeException 将触发事务回滚,但是任何 checked Exception 将不触发事务回滚 这些默认的设置当然也是可以被改变的. <tx:advi

Spring AOP声明式事务异常回滚

转:http://hi.baidu.com/iduany/item/20f8f8ed24e1dec5bbf37df7 近日测试用例,发现这样一个现象:在业务代码中,有如下两种情况,比如:throw new RuntimeException("xxxxxxxxxxxx"); 事物回滚throw new Exception("xxxxxxxxxxxx"); 事物没有回滚 自以为很了解事物,或许时间久远的缘故,没分析出来何故,遂查阅了下资料,写下了如下的内容,供参考: 1

spring 声明式事务管理注解方式实现

使用注解实现Spring的声明式事务管理,更加简单! 步骤: 1) 必须引入Aop相关的jar文件 2) bean.xml中指定注解方式实现声明式事务管理以及应用的事务管理器类 3)在需要添加事务控制的地方,写上: @Transactional @Transactional注解: 1)应用事务的注解 2)定义到方法上: 当前方法应用spring的声明式事务 3)定义到类上:   当前类的所有的方法都应用Spring声明式事务管理; 4)定义到父类上: 当执行父类的方法时候应用事务. 案例: 1.

全面分析 Spring 的编程式事务管理及声明式事务管理--转

开始之前 关于本教程 本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本教程假定您已经掌握了 Java 基础知识,并对 Spring 有一定了解.您还需要具备基本的事务管理的知识,比如:事务的定义,隔离级别的概念,等等.本文将直接使用这些概念而不做详细解释.另外,您最好掌握数据库的基础知识,虽然这不是必须. 系统需求 要试验这份教程中的工具和示例,硬件配置需求为:至少带

spring声明式事务管理

Spring 的声明式事务管理在底层是建立在 AOP 的基础之上的.其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务. 声明式事务管理分为两种:1.配置文件   2.注解 1.配置文件(声明式事务管理)用法: 在applicationContext.xml配置文件中配置①事务管理器(事务管理者).②事务参数(事务通知).③AOP配置 如下: applicationContext.xml配置文件代码 1 <!-- 事务管理器(