spring的事务管理,本文的例子是:比如你需要网购一本书,卖书的那一方有库存量以及书的价格,你有账户余额。回想我们在编程中要实现买书这样的功能,由于你的账户表和书的库存量表肯定不是同一张数据库表,所以必定会有一个先后,要么先将账户余额扣除书的价格,紧接着将书的库存量减一,要么反过来。那么问题来了,假如我们先将你的账户余额减掉,然后发现书的库存不足,这时怎么办呢,这就需要事务了,当我们发现书的库存不足时就要回滚事务,将你的余额返回去。只要配置了事务,发生了异常,就回滚。这就是事务的回滚。注:新人理解,如有错误,望指正,谢谢。

配置文件applicationContext.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:p="http://www.springframework.org/schema/p"
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-4.1.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:property-placeholder location="classpath:jdbc.properties"/> <!-- 配置c3p0数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${user}"></property>
<property name="password" value="${password}"></property>
<property name="driverClass" value="${driverClass}"></property>
<property name="jdbcUrl" value="${jdbcUrl}"></property> <property name="initialPoolSize" value="${initPoolSize}"></property>
<property name="maxPoolSize" value="${maxPoolSize}"></property>
</bean> <!-- 配置自动扫描的包 -->
<context:component-scan base-package="spring"></context:component-scan> <!-- 配置spring 的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>

applicationContext.xml

配置文件jdbc.propertices:

user=root
password=123
driverClass=com.mysql.jdbc.Driver
jdbcUrl=jdbc\:mysql\:///spring?encoding\=UFT-8
initPoolSize=5
maxPoolSize=20

BookShopDao.java:

package spring.tx;

public interface BookShopDao {

    public int findBookPriceByIsbn(String isbn);
public void updataBookStock(String isbn);
public void updataUserAccount(String username,int price);
}

BookShopDaoImp.java:

 package spring.tx;

 import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository; @Repository("bookShopDao")
public class BookShopDaoImp implements BookShopDao { @Autowired
private JdbcTemplate jdbcTemplate; @Override
public int findBookPriceByIsbn(String isbn) {
String sql = "select price from book where isbn=?";
return jdbcTemplate.queryForObject(sql, Integer.class, isbn);
} @Override
public void updataBookStock(String isbn) {
// 检查书的库存是否不够
String sql1 = "select stock from book_stock where isbn=?";
if (jdbcTemplate.queryForObject(sql1, Integer.class, isbn) <= 0) {
throw new BookStockException("库存不足");
}
String sql = "update book_stock set stock=stock-1 where isbn=?";
jdbcTemplate.update(sql, isbn);
} @Override
public void updataUserAccount(String username, int price) {
// 检查余额是否足够
String sql1 = "select balance from account where username=?";
if (jdbcTemplate.queryForObject(sql1, Integer.class, username) < price) {
throw new UserAccountException("余额不足");
}
String sql = "update account set balance = balance - ? where username=?";
jdbcTemplate.update(sql, price, username);
} }

BookShopDaoImp

BookShopService.java:

package spring.tx;

public interface BookShopService {
public void purchase(String username,String isbn);
}

BookShopServiceImpl.java:

 package spring.tx;

 import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository; @Repository("bookShopDao")
public class BookShopDaoImp implements BookShopDao { @Autowired
private JdbcTemplate jdbcTemplate; @Override
public int findBookPriceByIsbn(String isbn) {
String sql = "select price from book where isbn=?";
return jdbcTemplate.queryForObject(sql, Integer.class, isbn);
} @Override
public void updataBookStock(String isbn) {
// 检查书的库存是否不够
String sql1 = "select stock from book_stock where isbn=?";
if (jdbcTemplate.queryForObject(sql1, Integer.class, isbn) <= 0) {
throw new BookStockException("库存不足");
}
String sql = "update book_stock set stock=stock-1 where isbn=?";
jdbcTemplate.update(sql, isbn);
} @Override
public void updataUserAccount(String username, int price) {
// 检查余额是否足够
String sql1 = "select balance from account where username=?";
if (jdbcTemplate.queryForObject(sql1, Integer.class, username) < price) {
throw new UserAccountException("余额不足");
}
String sql = "update account set balance = balance - ? where username=?";
jdbcTemplate.update(sql, price, username);
} }

BookShopServiceImpl.java

Cashier.java:

package spring.tx;

import java.util.List;

public interface Cashier {
public void checkout(String username,List<String> isbns);
}

CashierImpl.java:

 package 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; @Transactional
@Override
public void checkout(String username, List<String> isbns) {
for (int i = 0; i < isbns.size(); i++) {
bookShopService.purchase(username, isbns.get(i));
}
} }

CashierImpl

定义两个异常类:

 package spring.tx;

 public class BookStockException extends RuntimeException{

     /**
*
*/
private static final long serialVersionUID = 1L; 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
} }

BookStockException

package spring.tx;

public class UrAccountExceptionse extends RuntimeException {

    /**
*
*/
private static final long serialVersionUID = 1L; 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
} }

UserAccountExceptionse

测试方法:

package spring.tx.test;

import java.util.ArrayList;
import java.util.List; import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import spring.tx.BookShopDao;
import spring.tx.BookShopService;
import spring.tx.Cashier; public class SpringTransactionTest { private ApplicationContext ctx=null;
private BookShopDao bookShopDao;
private BookShopService bookShopService;
private Cashier cashier;
{
ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
bookShopDao =(BookShopDao) ctx.getBean("bookShopDao");
bookShopService=(BookShopService) ctx.getBean("bookShopService");
cashier =(Cashier) ctx.getBean("cashier");
} @Test
public void testTransactionPropagation(){
List<String > isbns=new ArrayList<String>();
isbns.add("1001");
isbns.add("1002");
cashier.checkout("aaa", isbns);
} @Test
public void testBookShopService() {
bookShopService.purchase("aaa", "1001");
} @Test
public void testupdataBookStock(){
bookShopDao.updataBookStock("1001");
} @Test
public void testUpdataUserAccount(){
bookShopDao.updataUserAccount("aaa", 200);
} @Test
public void testBookShopDao(){
int price=bookShopDao.findBookPriceByIsbn("1001");
System.out.println(price); }
}

Spring初学之spring的事务管理注解的更多相关文章

  1. Spring初学之spring的事务管理xml

    所有的java类都是用的上一篇文章:Spring初学之spring的事务管理 不同的是,这时xml配置事务,所以就要把java类中的那些关于spring的注解都删掉,然后在xml中配置,Applica ...

  2. spring+mybatis之声明式事务管理初识(小实例)

    前几篇的文章都只是初步学习spring和mybatis框架,所写的实例也都非常简单,所进行的数据访问控制也都很简单,没有加入事务管理.这篇文章将初步接触事务管理. 1.事务管理 理解事务管理之前,先通 ...

  3. java框架之Spring(3)-JDBC模板使用&事务管理

    下面内容使用到的 jar 包下载 JDBC模板使用 入门 1.导包,如要导入 Spring 的基本开发包.数据库驱动包.Spring 提供的 JDBC 模板包,如下: 2.测试: @Test publ ...

  4. spring boot配置mybatis和事务管理

    spring boot配置mybatis和事务管理 一.spring boot与mybatis的配置 1.首先,spring boot 配置mybatis需要的全部依赖如下: <!-- Spri ...

  5. Spring 简单而强大的事务管理功能

    开始之前 关于本教程 本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本 ...

  6. 深入学习Spring框架(四)- 事务管理

    1.什么是事务? 事务(Transaction)是一个操作序列.这些操作要么都做,要么都不做,是一个不可分割的工作单位,是数据库环境中的逻辑工作单位.事务是为了保证数据库的完整性.例如:A给B转账,需 ...

  7. Spring—SSJ集成&声明式事务管理

    1.   课程介绍 1.  SSJ集成;(掌握) 2.  声明式事务管理;(掌握) 什么是三大框架 2.1.  ssh Struts/Struts2 Spring Hibernate 2.2.  ss ...

  8. Spring+JTA+Atomikos+mybatis分布式事务管理

    我们平时的工作中用到的Spring事务管理是管理一个数据源的.但是如果对多个数据源进行事务管理该怎么办呢?我们可以用JTA和Atomikos结合Spring来实现一个分布式事务管理的功能.了解JTA可 ...

  9. Spring MVC 中使用AOP 进行事务管理--注解实现

    注解实现实现事务管理很简单,和配置式差不多,配置文件的头文件也要加相应的支持.配置数据源,并开启事务管理支持即可. <bean id="transactionManager" ...

随机推荐

  1. 【BZOJ1925】[Sdoi2010]地精部落 组合数+DP

    [BZOJ1925][Sdoi2010]地精部落 Description 传说很久以前,大地上居住着一种神秘的生物:地精. 地精喜欢住在连绵不绝的山脉中.具体地说,一座长度为 N 的山脉 H可分 为从 ...

  2. FZU 1063 三维扫描(三维连通块)

    Accept: 415    Submit: 1291 Time Limit: 1000 mSec    Memory Limit : 32768 KB  Problem Description 工业 ...

  3. js特殊字符过滤

    //匹配中文 数字 字母 下划线 var checkInput = function (str) { var pattern =var pattern = /^[\w\u4e00-\u9fa5]+$/ ...

  4. 作为一名合格的JAVA程序员需要点亮那些技能树?

    以下是出现次数超过100的一些技能,大家可以做一个参考. Spring 299 MySQL 290 JavaScript 216Linux 165J2EE 151设计模式 148Struts2 138 ...

  5. 外部导入js(javascript)文件方法

    <script src="myScript.js"></script>

  6. 使用openresty + lua 搭建api 网关(一)安装openresty ,并添加lua模块

    openresty 有点不多说,网上各种介绍,先安装吧. 官方操作在此,http://openresty.org/cn/installation.html, tar -xzvf openresty-V ...

  7. hadoop学习第二天-了解HDFS的基本概念&&分布式集群的搭建&&HDFS基本命令的使用

    一.HDFS的相关基本概念 1.数据块 1.在HDFS中,文件诶切分成固定大小的数据块,默认大小为64MB(hadoop2.x以后是128M),也可以自己配置. 2.为何数据块如此大,因为数据传输时间 ...

  8. numpy的random模块详细解析

    随机抽样 (numpy.random) 简单的随机数据 rand(d0, d1, ..., dn) 随机值 >>> np.random.rand(3,2) array([[ 0.14 ...

  9. 剑指offer 面试15题

    面试15题: 题目:二进制中1的个数 题:输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 解题思路一: 最佳方法:把一个整数减去1,再和原整数做“与运算”,会把该整数最右边的1变成0 ...

  10. [JavaScript]常用的页面倒计时

    倒计时是web开发中比较常用的,以下列出常用的几个倒计时方法,仅供参考: 一 :页面倒计时 原理一般都是通过 setTimeout 或 setInterval 函数实现,下面是一个最简单的倒计时 &l ...