Spring学习笔记事务(二)

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



用 @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");
    }
}

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

时间: 2024-10-22 11:31:42

Spring学习笔记事务(二)的相关文章

Java框架spring 学习笔记(二十):事务管理(注解管理)

注解管理的方式要比xml配置方式要简单很多 只需在配置文件中添加事务注解 1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:tx="http://www.springframework.org/schema/tx" 4 xmlns:aop=&

Spring学习笔记事务(三)

鲁春利的工作笔记,好记性不如烂笔头 用事务通知声明式地管理事务 Spring的声明式事务管理是通过Spring AOP实现的,事务管理是一种横切关注点.

Spring学习笔记事务(一)

鲁春利的工作笔记,好记性不如烂笔头 事务是一系列操作组成的工作单元,是不可分割的,即要么所有操作都做,要么所有操作都不做,这就是事务.事务必需满足ACID(原子性.一致性.隔离性和持久性)特性,缺一不可:    原子性(Atomicity):即事务是不可分割的最小工作单元,事务内的操作要么全做,要么全不做:    一致性(Consistency):在事务执行前数据库的数据处于正确的状态,而事务执行完成后数据库的数据还是处于正确的状态:    隔离性(Isolation):并发事务执行之间无影响,

Spring 学习笔记(二)

  一.Spring 中的bean配置 –配置形式:基于 XML 文件的方式:基于注解的方式 –Bean 的配置方式:通过全类名(反射).通过工厂方法(静态工厂方法 & 实例工厂方法).FactoryBean –IOC 容器 BeanFactory & ApplicationContext 概述 –依赖注入的方式:属性注入:构造器注入 –注入属性值细节 –自动转配 –bean 之间的关系:继承:依赖 –bean 的作用域:singleton:prototype:WEB 环境作用域 –使用外

Spring 学习笔记(二)—— IOC 容器(BeanFactory)

使用Spring IoC容器后,容器会自动对被管理对象进行初始化并完成对象之间的依赖关系的维护,在被管理对象中无须调用Spring的API. 为了实现IoC功能,Spring提供了两个访问接口: org.springframework.beans.factory.BeanFactory org.springframework.context.ApplicationContext 前者为Bean工厂,借助于配置文件能够实现对JavaBean的配置和管理,用于向使用者提供Bean的实例: 后者为Ap

Spring学习笔记之二

在Spring配置文件中,通常使用<aop:config>元素来设置AOP,其中应包括: <aop:aspect>指定aspect,aspect是一个POJO类,包含了很多的advice:advice是aspect中的方法,它包含了要应用在切面上的逻辑: <aop:pointcut>指定pointcut,pointcut是一个表达式,用于指定在哪些对象或者类型上应用aspect的advice: <aop:before>, <aop:after>,

Spring boot 学习笔记 (二)- 整合MyBatis

Spring boot 学习笔记 (二)- 整合MyBatis Spring Boot中整合MyBatis,并通过注解方式实现映射. 整合MyBatis 以Spring boot 学习笔记 (一)- Hello world 为基础项目,在pom.xml中添加如下依赖 <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter&l

spring学习笔记(一) Spring概述

博主Spring学习笔记整理大部分内容来自Spring实战(第四版)这本书.  强烈建议新手购入或者需要电子书的留言. 在学习Spring之前,我们要了解这么几个问题:什么是Spring?Spring的优势在哪里?怎么系统的学习Spring? 一.什么是Spring? Spring是一个开源的轻量级Java SE(Java 标准版本)/Java EE(Java 企业版本)开发应用框架,其目的是用于简化企业级应用程序开发. 那有人就会问了,Spring是如何简化开发的? 在传统开发中,一个应用是需

不错的Spring学习笔记(转)

Spring学习笔记(1)----简单的实例 ---------------------------------   首先需要准备Spring包,可从官方网站上下载.   下载解压后,必须的两个包是spring.jar和commons-logging.jar.此外为了便于测试加入了JUnit包.   在Myeclipse中创建Java项目.   编写一个接口类,为了简单,只加入了一个方法.   Java代码   1.package com.szy.spring.interfacebean;