声明式事务

直接上代码:

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

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: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="dataSourceTransactionManager" 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 interface BookShopDao {
//根据书号获取书的单价
public int findBookPriceIsbn(String isbn); //更新书的库存,使书号对应的库存-1
public void updateBookStock(String isbn); public void updateUserAccount(String username,int price); }
package logan.study.spring.tx;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository; @Repository("bookShopDao")
public class BookShopDaoImpl implements BookShopDao { @Autowired
private JdbcTemplate jdbcTemplate; @Override
public int findBookPriceIsbn(String isbn) {
// TODO Auto-generated method stub
String sql = "SELECT price FROM book WHERE isbn=?";
return jdbcTemplate.queryForObject(sql, Integer.class, isbn);
} @Override
public void updateBookStock(String isbn) {
// TODO Auto-generated method stub
//检查书的库存是否足够,若不够,则抛出异常
String sql2 = "SELECT stock FROM book_stock WHERE isbn = ?";
int stock = jdbcTemplate.queryForObject(sql2, Integer.class, isbn);
if(stock == 0){
throw new BookStockException("库存不足!");
}
String sql = "UPDATE book_stock SET stock = stock -1 WHERE isbn = ?";
jdbcTemplate.update(sql, isbn); } @Override
public void updateUserAccount(String username, int price) {
// TODO Auto-generated method stub
//检查书的库存是否足够,若不够,则抛出异常
String sql2 = "SELECT balance FROM account WHERE username = ?";
int balance = jdbcTemplate.queryForObject(sql2, Integer.class, username);
if(balance < price){
throw new UserAccountException("余额不足!");
}
String sql = "UPDATE account SET balance = balance - ? WHERE username = ?";
jdbcTemplate.update(sql, price, username); } }
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 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 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); } }

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

  1. Spring入门第二十三课

    我们看基于XML配置的方式配置AOP 看代码: package logan.study.aop.impl; public interface ArithmeticCalculator { int ad ...

  2. Spring入门第二十一课

    切面优先级 先看代码: package logan.study.aop.impl; public interface ArithmeticCalculator { int add(int i, int ...

  3. Spring入门第二十课

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

  4. NeHe OpenGL教程 第二十七课:影子

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

  5. Spring入门第二课

    看代码 package logan.spring.study; public class HelloWorld { private String name; public void setName2( ...

  6. Spring入门第二课:Spring配置Bean的细节

    1.配置bean的作用域: 通过配置scope属性可以bean的作用域,参数有 prototype.request.session.singleton. 1)singleton为单例,IoC容器只会创 ...

  7. Spring入门第二十九课

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

  8. Spring入门第二十八课

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

  9. Spring入门第二十六课

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

随机推荐

  1. HDU2544最短路模板,

    #include<iostream> #include<stdio.h> #include<stdlib.h> #include<algorithm> ...

  2. SrpingCloud 之SrpingCloud config分布式配置中心搭建

    1.搭建git环境   目的:持久化存储配置文件信息 采用码云 创建后 继续创建文件夹  用来区分不同的项目 下面就是git上存放配置文件了.环境的区分 dev  sit pre prd   开发  ...

  3. TMS Scripter importtool的使用

    uses ap_DateUtils; showmessage(dayof(now)); //注册delphi对象或变量 : IDEScripter1   IDEScripter1.AddConstan ...

  4. Oracle可能会遇到问题和解决方法

    1.plsql developer查询一列用中文,出现乱码 添加环境变量NLS_LANG = SIMPLIFIED CHINESE_CHINA.ZHS16GBK->软件重启 2.ORA-1251 ...

  5. Spark- RDD简介

    Spark里面提供了一个比较重要的抽象——弹性分布式数据集(resilient distributed dataset),简称RDD.弹性:数据可大可小,可分布在内存或磁盘,当某台机器宕机时,能够按照 ...

  6. Linux下查看Python安装了哪些脚本模块

    Linux下查看Python安装了哪些脚本模块 1.什么是rpm ? rpm 即RedHat Package Management,是RedHat的发明之一 .现在包括OpenLinux.fedora ...

  7. ubantu卸载软件

    参考:https://blog.csdn.net/luckydog612/article/details/80877179 https://blog.csdn.net/get_set/article/ ...

  8. HDU 2089 不要62:数位dp

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089 题意: 问你在区间[n,m]中,有多少个数字不含"4"且不含"62 ...

  9. Linux课程---2、Linux下最常用命令(查看帮助命令)

    Linux课程---2.Linux下最常用命令(查看帮助命令) 一.总结 一句话总结: man 1.显示文件? ls:ls带其它参数详情可以man ls man ls:比如 ls -a显示隐藏文件,l ...

  10. WCF之契约的分类(部分為參考他人)

    什么是契约呢?在使用WCF时,对其制定各种各样的规则,就叫做WCF契约.任何一个分布式的应用程序在传递消息的时候都需要实现制定一个规则. 任何一个分布式应用程序,它之所以能够互相传递消息,都是事先制定 ...