实现的效果是:  用户在购买股票的时候,钱减少!股票增加!

模拟出现的问题是!  用户在购买股票的时候,钱减少! 股票没有增加!

01.创建对应的数据库

02.创建对应实体类

public class Account {  //银行账户
private Integer aid;
private double money;
private String aname;
public Integer getAid() {
return aid;
}
public void setAid(Integer aid) {
this.aid = aid;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
public String getAname() {
return aname;
}
public void setAname(String aname) {
this.aname = aname;
}
public Account(Integer aid, double money, String aname) {
super();
this.aid = aid;
this.money = money;
this.aname = aname;
}
@Override
public String toString() {
return "Account [aid=" + aid + ", money=" + money + ", aname=" + aname
+ "]";
} }

Account

public class Stock {  //股票

    private Integer sid;
private Integer amount;
private String sname;
public Integer getSid() {
return sid;
}
public void setSid(Integer sid) {
this.sid = sid;
}
public Integer getAmount() {
return amount;
}
public void setAmount(Integer amount) {
this.amount = amount;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public Stock(Integer sid, Integer amount, String sname) {
super();
this.sid = sid;
this.amount = amount;
this.sname = sname;
}
public Stock() {
super();
}
@Override
public String toString() {
return "Stock [sid=" + sid + ", amount=" + amount + ", sname=" + sname
+ "]";
} }

Stock

03.创建对应的dao

public interface StockDao {

      //股票开户
void openStock(String sName,Integer amount); //增加股票
void updateStock(String sName,Integer amount);
}
public interface AccoutDao {

      //银行开户
void openAccount(String aName,double money); //购买股票
void updateAccount(String aName,double money); }

04.创建对应的service和自定义的异常类

public interface StockService {

      //股票开户
void openStock(String sName,Integer amount);
//银行开户
void openAccount(String aName,double money); /**
* 谁花了多少钱 买了 多少股票??
*/
void buyStock(String name,double money,Integer amount) throws BuyStockException; }
/**
* @Transactional
* isolation:事务的隔离级别
* propagation:事务的传播行为
* rollbackFor :需要回滚的异常类! 类型是Class
* readOnly:对数据库的操作 只读! 默认false!
* timeout:设置与数据库连接的超时时间! 单位是S! 默认值 -1!
*/
public class StockServiceImpl implements StockService { private StockDao stockDao;
private AccoutDao accountDao; //股票开户
@Transactional(isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED)
@Override
public void openStock(String sName, Integer amount) {
stockDao.openStock(sName, amount);
} //银行开户
@Transactional(isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED)
@Override
public void openAccount(String aName, double money) {
accountDao.openAccount(aName, money);
} /**
* 谁花了多少钱 买了 多少股票??
*
* 01.减钱
* 02.加股
* @throws BuyStockException
*/
@Transactional(rollbackFor=BuyStockException.class,isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED)
@Override
public void buyStock(String name, double money, Integer amount) throws BuyStockException {
//银行账户减钱
accountDao.updateAccount(name, money);
if(1==1){ //模拟异常
throw new BuyStockException("!!!购买股票失败.......");
}
stockDao.updateStock(name, amount);
} public StockDao getStockDao() {
return stockDao;
} public void setStockDao(StockDao stockDao) {
this.stockDao = stockDao;
} public AccoutDao getAccountDao() {
return accountDao;
} public void setAccountDao(AccoutDao accountDao) {
this.accountDao = accountDao;
} }
/**
* 自定义异常类
*/
public class BuyStockException extends Exception { public BuyStockException(String msg){
super(msg);
}
}

05.创建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:c="http://www.springframework.org/schema/c"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
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.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
"> <!-- 01.spring默认的数据源
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///spring"/>
<property name="username" value="t11"/>
<property name="password" value="t11"/>
</bean> --> <!-- 02.dbcp数据源
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///spring"/>
<property name="username" value="t11"/>
<property name="password" value="t11"/>
</bean>-->
<!-- 加载配置文件 数据库需要的4要素 -->
<context:property-placeholder location="classpath:jdbc.properties"/> <!-- 03.c3p0数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.userName}"/>
<property name="password" value="${jdbc.password}"/>
</bean> <!-- 配置stockDao -->
<bean id="stockDao" class="cn.bdqn.dao.impl.StockDaoImpl" p:dataSource-ref="dataSource"/>
<!-- 配置accountDao -->
<bean id="accountDao" class="cn.bdqn.dao.impl.AccountDaoImpl" p:dataSource-ref="dataSource"/> <!-- 配置stockService -->
<bean id="stockService" class="cn.bdqn.service.impl.StockServiceImpl"
p:accountDao-ref="accountDao" p:stockDao-ref="stockDao"/> <!-- ==================================事务的配置=========================================-->
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean> <!-- 03.使用注解管理事务 -->
<tx:annotation-driven transaction-manager="transactionManager"/> <!-- 01.使用代理工厂管理事务 -->
<!-- <bean id="serviceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager"/>绑定事务管理器
<property name="target" ref="stockService"/> 声明需要代理的bean
<property name="transactionAttributes">
<props>在指定的切入点上配置事务属性
<prop key="open*">ISOLATION_DEFAULT,PROPAGATION_REQUIRED</prop>
-:发生异常回滚 +:发生异常提交
<prop key="buyStock">ISOLATION_DEFAULT,PROPAGATION_REQUIRED,-BuyStockException</prop>
</props>
</property>
</bean> --> <!-- 02.使用AspectJ来管理事务
切入点的匹配表达式
public * addStock(Stock stock) : * 代表匹配所有的返回值类型
public void *(Stock stock) : * 代表匹配所有没有返回值的方法
public void addStock(..) : .. 匹配所有的参数以及类型
* cn.bdqn.service.*.*(..) : 匹配cn.bdqn.service包下所有类的所有方法
* cn.bdqn.service..*(..) : 匹配cn.bdqn.service包以及子包下所有类的所有方法
* *..service.*.*(..) : 匹配包名有service的包下所有类的所有方法 !!常用!!
--> <!-- <tx:advice id="txAdvice" transaction-manager="transactionManager">绑定事务管理器
在连接点的方法上进行事务的属性配置
<tx:attributes>
<tx:method name="open*" isolation="DEFAULT" propagation="REQUIRED"/>
<tx:method name="buyStock" isolation="DEFAULT" propagation="REQUIRED" rollback-for="BuyStockException"/>
</tx:attributes>
</tx:advice> 指定切入点
<aop:config>
<aop:pointcut expression="execution(* *..service.*.*(..))" id="myPoint"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="myPoint"/>
</aop:config> --> </beans>

06.创建对应的测试类

public class StockTest {

    public static void main(String[] args) throws BuyStockException {

        ApplicationContext context  =new  ClassPathXmlApplicationContext("applicationContext.xml");
StockService service=(StockService) context.getBean("stockService");
//service.openAccount("小猪", 5000);service.openStock("小猪", 20);
service.buyStock("小猪", 250, 1);
} // 01.使用代理工厂 管理事务
@Test
public void testProxy() throws BuyStockException{
ApplicationContext context =new ClassPathXmlApplicationContext("applicationContext.xml");
StockService service=(StockService) context.getBean("serviceProxy");
service.buyStock("小猪", 250, 1);
} // 02.使用AspectJ 和注解
@Test
public void testAop() throws BuyStockException{
ApplicationContext context =new ClassPathXmlApplicationContext("applicationContext.xml");
StockService service=(StockService) context.getBean("stockService");
service.buyStock("小猪", 250, 1);
} }
public class ReadeMe {
/**
* 事务:一个或者一组sql语句来完成一个功能!
* 事务具有的四个特性: ACID特性!
* 01.原子性:一个事物都是一个不可分割的单位!所有的操作 要么都执行,要么都不执行!
* 02.一致性:事务必须是数据库从一个一致性的状态到达另一个一致性的状态!
* 03.隔离性:一个事务的执行不会被其他的事务干扰!事务之间相互独立!
* 04.持久性:事务一旦被提交!这个操作对数据库来说是永久性的!
*
*
* Spring的事务管理:
* 事务本事是数据库中的概念! 按理说应该在数据访问层(dao)!
*
* 绝大多数的情况下,我们是把事务 提升到 业务逻辑层!
* 01.使用spring的事务代理工厂 来 管理事务!
* 02.使用spring的注解 来 管理事务! 常用
* 03.使用AspectJ的AOP配置 来 管理事务! 常用
*
* 需要掌握的两个属性名:
*
* isolation:事务的隔离级别!
* 01.default:采用数据库默认的事务隔离级别
* 001.mysql ---》repeatable-read
* 002.oracle---》read_committed
* 02. repeatable-read:可重复读取!解决了脏读,不可重复读,没解决幻读!
* 03. read_committed:读已提交! 解决了脏读,没解决不可重复读,幻读!
* 04. read_uncommitted:读未提交!什么都没有解决!
* 05. serializable:串行化!级别最高!效率最低!不存在并发的问题!
*
*
* propagation: 事务的传播行为:一共7中方式!
* 01.required:是spring默认的事务传播行为!
* 指定的方法必须在事务中执行!如果没有事务,则会自动创建一个事务!
* 02.supports:有事务就在事务环境下执行,没有事务就直接执行!
* 03.mandatory:
* 指定的方法必须在事务中执行!如果没有事务,则抛出异常!
* 04.requires_new:总是新创建一个事务!
* 如果当前方法存在事务,则把当前的事务挂起,直到新创建的事务执行完毕后执行!
* 05.not_supported:指定的方法不能在事务中执行!如果当前方法存在事务,则把当前的事务挂起!
* 06.never:指定的方法不能在事务中执行!如果当前方法存在事务,则抛出异常!
* 07.nested:指定的方法必须在事务内执行!
* 如果执行的方法没有事务,则会创建一个事务!
* 如果执行的方法没有事务,则会嵌套执行!
*
* timeout_default:定义了事务默认的超时时间!
*
*
* Spring事务管理的接口:PlatformTransactionManager
* 常用的两个实现类:
* 01.使用jdbc和MyBatis时 使用DataSourceTrancationManager
* 02.使用hibernate时 使用HibernateTrancationManager
*
* Spring事务回滚的方式:
* 默认的回滚方式--》发生运行时异常回滚!发送受查异常时提交!
* 受查异常肯定需要我们手动的设置回滚方式!
* 运行时异常严重!一旦发生,JVM中止执行!
*
* 实现自定义异常类!RuntimeException --> Exception ---> Throwable
*
*/
}

spring08事务的更多相关文章

  1. Spring基于AOP的事务管理

                                  Spring基于AOP的事务管理 事务 事务是一系列动作,这一系列动作综合在一起组成一个完整的工作单元,如果有任何一个动作执行失败,那么事务 ...

  2. SQLServer事务同步下如何收缩日志

    事务同步是SQLServer做读写分离的一种常用的方式. 随着业务数据的不断增长,数据库积攒了大量的日志,为了腾出硬盘空间,需要对数据库日志进行清理 订阅数据库的日志清理 因为订阅数据库所有的数据都来 ...

  3. 事务日志已满,原因为“ACTIVE_TRANSACTION”

    汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 异常处理汇总-数据库系列  http://www.cnblogs.com/dunitia ...

  4. Mysql事务探索及其在Django中的实践(二)

    继上一篇<Mysql事务探索及其在Django中的实践(一)>交代完问题的背景和Mysql事务基础后,这一篇主要想介绍一下事务在Django中的使用以及实际应用给我们带来的效率提升. 首先 ...

  5. Mysql事务探索及其在Django中的实践(一)

    前言 很早就有想开始写博客的想法,一方面是对自己近期所学知识的一些总结.沉淀,方便以后对过去的知识进行梳理.追溯,一方面也希望能通过博客来认识更多相同技术圈的朋友.所幸近期通过了博客园的申请,那么今天 ...

  6. CRL快速开发框架系列教程七(使用事务)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  7. 玩转spring boot——结合JPA事务

    接着上篇 一.准备工作 修改pom.xml文件 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=&q ...

  8. MySQL 系列(三)你不知道的 视图、触发器、存储过程、函数、事务、索引、语句

    第一篇:MySQL 系列(一) 生产标准线上环境安装配置案例及棘手问题解决 第二篇:MySQL 系列(二) 你不知道的数据库操作 第三篇:MySQL 系列(三)你不知道的 视图.触发器.存储过程.函数 ...

  9. PHP中PDO事务的使用方法

    事务 (Transaction) 是操作数据库中很重要的一个功能, 它可以让你预定一条, 或者一系列 SQL 语句, 然后一起执行. 在执行的过程中, 如果其中的某条执行失败, 可以回滚所有已更改的操 ...

随机推荐

  1. bitmap位图法

    位图法定义 位图法就是bitmap的缩写,所谓bitmap,是用每一位来存放某种状态,适用于大规模数据,但数据状态又不是很多的情况.通常是用来判断某个数据存不存在的. 例如,要判断一千万个人的状态,每 ...

  2. MYSQL SET ENUM字段类型

    show create table stu;//显示建表语句 create table t1(t enum('a','b','c')); insert into t1 values('a'); cre ...

  3. java 多线程 day01 创建线程

    线程,即代码的执行路径java 面向对象编程.所以线程在java中也是用对象来表示的,创建线程对象的类就是 Thread如下代码即开启一个新的线程,通过线程对象的start方法,即可启动线程 Thre ...

  4. jmeter+ant+jenkins接口自动环境搭建

    ant 下载地址:http://archive.apache.org/dist/ant/binaries/ 下载:apache-ant-1.9.7-bin.zip 解压到系统盘下:D:\apache- ...

  5. PySpider HTTP 599: SSL certificate problem错误的解决方法(转)

    前言 最近发现许多小伙伴在用 PySpider 爬取 https 开头的网站的时候遇到了 HTTP 599: SSL certificate problem: self signed certific ...

  6. NHibernate之配置文件属性说明

    一.NHibernate配置所支持的属性 属性名 用途 dialect 设置NHibernate的Dialect类名 - 允许NHibernate针对特定的关系数据库生成优化的SQL 可用值: ful ...

  7. Java基础教程:Lambda表达式

    Java基础教程:Lambda表达式 本文部分内容引用自OneAPM:http://blog.oneapm.com/apm-tech/226.html 引入Lambda Java 是一流的面向对象语言 ...

  8. 笔记-CSS空背景图片会导致页面被加载两次

    如果页面样式的背景图片路径设置为'' 或 '#', 会导致页面被重复加载两次 (Chrome.56.0.2924.87 测试) 因为:空图片路径属性值,默认加载当前页面的URL作为图片路径 Safar ...

  9. PAT 天梯赛 L1-004. 计算摄氏温度 【水】

    题目链接 https://www.patest.cn/contests/gplt/L1-004 AC代码 #include <iostream> #include <cstdio&g ...

  10. orecle 函数

    --创建函数语法 create [or replace] function [schema.]function_name (函数参数列表) --参数有IN.OUT.IN OUT三种类型:IN代表需要输 ...