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. idea 右下角不显示git分支

    开发工程中遇到idea右下角不显示git分支问题: 解决方案:查找资料说是需要打开VCS->Enable version control. 但是Enable version control 已经 ...

  2. oracle clob字段去除html标签

    通过正则表达式的方式去除html标签 select regexp_replace(content,'</?[^>]*>|nbsp;|&','') content from T ...

  3. js HTML DOM TableRow 对象(innerHTML)

    TableRow 对象 TableRow 对象代表一个 HTML 表格行. 在 HTML 文档中 <tr> 标签每出现一次,一个 TableRow 对象就会被创建. TableRow 对象 ...

  4. Introduction to Mathematical Thinking - Week 2

    基本数学概念 real number(实数):是有理数和无理数的总称 有理数:可以表达为两个整数比的数(a/b, b!=0) 无理数是指除有理数以外的实数 imply -- 推导出 不需要 A 能推导 ...

  5. 阻止element组件中的<el-input/>的粘贴功能

    需求: 阻止element组件中的<el-input/>的粘贴功能 实现思路: <el-input/>组件是由外层<div>和内层的<input>组成的 ...

  6. JS添加标签

    <script>            function show(){                $('.add').unbind();                $('.low ...

  7. K-M-P

    分段K-M-P 只需要记录上一段已经匹配了的长度,再接着从匹配下一段就可以了.

  8. 5 Best VPNs for Ubuntu

    https://www.bestvpn.com/blog/6268/5-best-vpns-for-ubuntu/?nabe=6412130213429248:0&utm_referrer=h ...

  9. 【python】判断字符串以什么开头或结尾

    项目中用到python判断一个字符串是否以某个字符串结尾,比如,筛选一个目录下所有以.mp4结尾的文件. >>> item = "demo.mp4" >&g ...

  10. 系统架构师考试——程序计数器 PC, 指令寄存器IR、状态寄存器SR、通用寄存器GR

    ● 计算机执行程序时,在一个指令周期的过程中,为了能够从内存中读指令操作码,首先是将__(9)___的内容送到地址总线上. (9)A.程序计数器PC    B.指令寄存器IR C.状态寄存器SR    ...