事务的传播行为

当事务方法被另一个事务方法调用时,必须指定事务应该如何传播,例如:方法可能继续在现有事务中运行,也可能开启一个新的事务,并在自己的事务中运行。

事务的传播行为可以由传播属性指定.Spring定义了7中类型的传播行为。

默认的传播行为是REQUIRED

直接看代码:

db.properties

jdbc.user=root
jdbc.password=logan123
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/spring jdbc.initPoolSize=5
jdbc.maxPoolSize=10
<?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/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> <context:component-scan base-package="logan.study.spring.tx"></context:component-scan> <!-- 导入资源文件 -->
<context:property-placeholder location="classpath:db.properties"/> <!-- 配置C3P0数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="driverClass" value="${jdbc.driverClass}"></property> <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
<property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
</bean> <!-- 配置Spring的JDBCTemplate -->
<bean id="jdbcTemplate"
class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean> <!-- 配置NamedParameterJdbcTemplate,该对象可以使用具名参数,其没有无参的构造器,所以必须为其构造器指定参数 -->
<bean id="namedParameterJdbcTemplate"
class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="dataSource"></constructor-arg>
</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 logan.study.spring.tx;

public class UserAccountException extends RuntimeException{

    public UserAccountException() {
super();
// TODO Auto-generated constructor stub
} public UserAccountException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
} public UserAccountException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
} public UserAccountException(String message) {
super(message);
// TODO Auto-generated constructor stub
} public UserAccountException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
} }
package logan.study.spring.tx;

public class BookStockException extends RuntimeException{

    public BookStockException() {
super();
// TODO Auto-generated constructor stub
} public BookStockException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
} public BookStockException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
} public BookStockException(String message) {
super(message);
// TODO Auto-generated constructor stub
} public BookStockException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
} }
package logan.study.spring.tx;

public interface BookShopService {

    public void purchase(String username, String isbn);

}
package logan.study.spring.tx;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; @Service("bookShopService")
public class BookShopServiceImpl implements BookShopService { @Autowired
private BookShopDao bookShopDao; //添加事务注解
@Transactional
@Override
public void purchase(String username, String isbn) {
// TODO Auto-generated method stub
//1.获取书的单价
int price = bookShopDao.findBookPriceIsbn(isbn);
//2.更新书的库存
bookShopDao.updateBookStock(isbn);
//3.更新用户余额
bookShopDao.updateUserAccount(username, price); } }
package logan.study.spring.tx;

import java.util.List;

public interface Cashier {
public void checkout(String username,List<String> isbns); }
package logan.study.spring.tx;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@Service("cashier")
public class CashierImpl implements Cashier{ @Autowired
private BookShopService bookShopService; /**
* 使用propagation指定事务的传播行为,即当前的事务方法被另外一个事务方法调用时
* 如何使用事务,默认取值为REQUIRED,即使用调用方法的事务
* REQUIRES_NEW事务自己的事务,调用事务方法的事务被挂起
*/
@Transactional(propagation=Propagation.REQUIRES_NEW)
@Override
public void checkout(String username, List<String> isbns) {
// TODO Auto-generated method stub
for(String isbn:isbns){
bookShopService.purchase(username, isbn);
} } }
package logan.study.spring.tx;

import static org.junit.Assert.*;

import java.util.Arrays;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate; public class SpringTransactionTest { private ApplicationContext ctx = null;
private BookShopDao bookShopDao = null;
private BookShopService bookShopService = null;
private Cashier cashier = null;
{
ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
bookShopDao = ctx.getBean(BookShopDao.class);
bookShopService = ctx.getBean(BookShopService.class);
cashier = ctx.getBean(Cashier.class);
} @Test
public void testTransactionalPropagation(){
cashier.checkout("AA", Arrays.asList("1001","1002"));
} @Test
public void testBookShopService(){
bookShopService.purchase("AA", "1001");
} @Test
public void testBookShopDaoUpdateUserAcount(){
bookShopDao.updateUserAccount("AA", 100);
} @Test
public void testBookShopDaoUpdateBookStock(){
bookShopDao.updateBookStock("1001");
} @Test
public void testBookShopDaoFindPriceByIsbn(){
System.out.println(bookShopDao.findBookPriceIsbn("1001"));
} @Test
public void test() {
fail("Not yet implemented");
} }

Spring入门第二十八课的更多相关文章

  1. Spring入门第二十九课

    事务的隔离级别,回滚,只读,过期 当同一个应用程序或者不同应用程序中的多个事务在同一个数据集上并发执行时,可能会出现许多意外的问题. 并发事务所导致的问题可以分为下面三种类型: -脏读 -不可重复读 ...

  2. Spring入门第二十六课

    Spring中的事务管理 事务简介 事务管理是企业级应用程序开发中必不可少的技术,用来确保数据的完整性和一致性. 事务就是一系列的动作,他们被当做一个单独的工作单元,这些动作要么全部完成,要么全部不起 ...

  3. Spring入门第二十五课

    使用具名参数 直接看代码: db.properties jdbc.user=root jdbc.password=logan123 jdbc.driverClass=com.mysql.jdbc.Dr ...

  4. Spring入门第二十四课

    Spring对JDBC的支持 直接看代码: db.properties jdbc.user=root jdbc.password=logan123 jdbc.driverClass=com.mysql ...

  5. Spring入门第二十二课

    重用切面表达式 我们有的时候在切面里面有多个函数,大部分函数的切入点都是一样的,所以我们可以声明切入点表达式,来重用. package logan.study.aop.impl; public int ...

  6. NeHe OpenGL教程 第二十八课:贝塞尔曲面

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  7. Spring入门第二十课

    返回通知,异常通知,环绕通知 看代码: package logan.study.aop.impl; public interface ArithmeticCalculator { int add(in ...

  8. Spring入门第十八课

    Spring AOP AspectJ:Java社区里最完整最流行的AOP框架 在Spring2.0以上的版本中,可以使用基于AspectJ注解或者基于XML配置的AOP 看代码: package lo ...

  9. 第二十八课:focusin与focusout,submit,oninput事件的修复

    focusin与focusout 这两个事件是IE的私有实现,能冒泡,它代表获得焦点或失去焦点的事件.现在只有Firefox不支持focusin,focusout事件.其实另外两个事件focus和bl ...

随机推荐

  1. hdu 5475 线段树

    An easy problem Time Limit: 8000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  2. jQuery应用之eraser.js使用,实现擦除、刮刮卡效果

    jquery.eraser是一款使用鼠标或触摸的动作来擦除画布显示真正图片的插件.jquery.eraser插件的原理是用一个画布遮住图片,然后根据触摸或鼠标输入来擦除画布显示图片,您可以在参数中指定 ...

  3. Linux课程---7、shell技巧(获取帮助命令)

    Linux课程---7.shell技巧(获取帮助命令) 一.总结 一句话总结: ls --help:简单手册 man ls:内容手册 1.tab补全? 命令+tab:加快敲命令敲文件目录的速度,多敲几 ...

  4. 分享知识-快乐自己:shiro 异常类型

    <!-- 身份认证异常 --> 1):身份令牌异常,不支持的身份令牌 --> org.apache.shiro.authc.pam.UnsupportedTokenException ...

  5. 理解WCF(第二部分,部分參考他人)

    該篇的主題:wcf到底是怎工作的? 一.什么是分布式: 首先看一张图: 由上图对比我们可以发现,区别就是前者把服务器放在了一台电脑上,而后者把服务器放在了多台电脑上.这样多台电脑处理起来的速度比一台电 ...

  6. log4j报错ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.

    ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only err ...

  7. hdu4699 Editor(双向链表或双栈对弹)

    本题就是两个要点: 1.数据结构的设计.显然可以使用双向链表来做,但是写双向链表的代码复杂度高.其实更好的方法是使用两个对弹的栈来做,而且没必要用STL的栈,就自己开两个数组简单搞一下就好了. 2.最 ...

  8. Android 中对于图片的内存优化方法

    Android 中对于图片的内存优化方法,需要的朋友可以参考一下     1. 对图片本身进行操作 尽量不要使用 setImageBitmap.setImageResource. BitmapFact ...

  9. POJ2406Power Strings (最小循环节)(KMP||后缀数组)

    Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc&quo ...

  10. Maven 将jar导入本地maven仓库

    目录 环境变量配置maven 执行一下命令即可 诚邀访问我的个人博客:我在马路边 更好的阅读体验点击查看原文:Maven将jar倒入本地maven仓库 原创博客,转载请注明出处 @ 在Java项目开发 ...