码迷,mamicode.com
首页 > 编程语言 > 详细

Spring学习笔记事务(二)

时间:2016-07-14 19:37:09      阅读:142      评论:0      收藏:0      [点我收藏+]

标签:声明式事务

鲁春利的工作笔记,好记性不如烂笔头



用 @Transactional 注解声明式地管理事务


Spring 还允许简单地用 @Transactional 注解来标注事务方法(只能标注公有方法)。
在 Bean 配置文件中增加 <tx:annotation-driven> 元素声明, 并为之指定事务管理器。如果事务处理器的名称是 transactionManager, 在<tx:annotation-driven> 元素中可以省略 transaction-manager 属性,元素会自动检测该名称的事务处理器。


Spring配置文件(spring-context-tx-program.xml)

<?xml version="1.0" encoding="UTF-8"?>
<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:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-4.2.xsd">

    <!-- 
        配置Spring进行组件扫描的路径
            base-package 属性指定一个需要扫描的基类包,Spring 容器将会扫描这个基类包里及其子包中的所有类,当需要扫描多个包时, 可以使用逗号分隔;
            resource-pattern 如果仅希望扫描特定的类而非基包下的所有类,如 resource-pattern="dao/*.class"; 
            <context:include-filter> 子节点表示要包含的目标类;
            <context:exclude-filter> 子节点表示要排除在外的目标类;
            <context:component-scan> 下可以拥有若干个 <context:include-filter> 和 <context:exclude-filter> 子节点;
            如:扫描符合@Service @Repository的类
            <context:include-filter type="annotation"
                    expression="org.springframework.stereotype.Service" />
            <context:include-filter type="annotation"
                    expression="org.springframework.stereotype.Repository" />
    -->
    <context:component-scan base-package="com.invicme.apps.tx.annotation" />
    
    <!-- 加载配置属性文件 -->
    <context:property-placeholder ignore-unresolvable="true" 
            location="classpath:spring/jdbc.properties" />
    
    <!-- 数据源配置, 使用 BoneCP 数据库连接池 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" 
            init-method="init" destroy-method="close"> 
        <!-- 略 -->
    </bean>
    
    <!-- 配置 Spirng 的 JdbcTemplate -->
    <bean id="jdbcTemplate" 
        class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    
    <!-- 配置事务管理器 -->
    <bean id="transactionManager" 
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    
    <!-- 启用事务注解 -->
    <tx:annotation-driven transaction-manager="transactionManager" />
    
</beans>


业务层实现

package com.invicme.apps.tx.annotation.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.invicme.apps.tx.annotation.dao.BookShopDao;

/**
 * 
 * @author lucl
 * 
 */
@Service("bookShopService")
public class BookShopServiceImpl implements BookShopService {

    @Autowired
    private BookShopDao bookShopDao;
    
    /**
     * 事务注解
     * 1.使用 propagation 指定事务的传播行为, 即当前的事务方法被另外一个事务方法调用时如何使用事务, 
     *     默认取值为 REQUIRED, 即使用调用方法的事务;
     *     REQUIRES_NEW: 事务自己的事务, 调用的事务方法的事务被挂起. 
     * 2.使用 isolation 指定事务的隔离级别, 最常用的取值为 READ_COMMITTED;
     * 3.默认情况下 Spring 的声明式事务对所有的运行时异常进行回滚. 也可以通过对应的属性进行设置. 通常情况下去默认值即可.
     * 4.使用 readOnly 指定事务是否为只读. 表示这个事务只读取数据但不更新数据, 可以帮助数据库引擎优化事务.
     * 5.使用 timeout 指定强制回滚之前事务可以占用的时间.  
     */
    @Transactional(propagation=Propagation.REQUIRED,
            isolation=Isolation.READ_COMMITTED,
            readOnly=false,
            timeout=3)
    @Override
    public void purchase(String ano, String isbn) {
        //1. 获取书的单价
        int price = bookShopDao.findBookPriceByIsbn(isbn);
        
        //2. 更新数的库存
        bookShopDao.updateBookStock(isbn);
        
        //3. 更新用户余额(抛出异常,第二步的操作也不会成功)
        bookShopDao.updateUserAccount(ano, price);
    }

}

单元测试类

public class TestAnnotationTransaction {
    @Test
    public void testAnnotationTransaction(){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("spring/spring-context-tx-annotation.xml");
        BookShopService bookShopService = ctx.getBean(BookShopService.class);
        bookShopService.purchase("zhangsan", "8888");
    }
}


用事务通知声明式地管理事务






本文出自 “闷葫芦的世界” 博客,请务必保留此出处http://luchunli.blog.51cto.com/2368057/1826446

Spring学习笔记事务(二)

标签:声明式事务

原文地址:http://luchunli.blog.51cto.com/2368057/1826446

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!