Hibernate学习5 事务管理简单例子购买股票
来源:互联网 发布:河北大学工商学院 知乎 编辑:程序博客网 时间:2024/05/16 11:36
Spring与JDBC模板 需要注意的是:
//getJdbcTemplate模板对象是多例的,只在一个方法内有效,当前线程有效,系统会为每一个使用模板对象的方法创建爱一个getJdbcTemplate模板,当
//该方法结束之后便自动销毁,只局限于当前方法 这个类的使用方法是错误的,会报空指针异常
private JdbcTemplate jt;
public StudentDaoImpl() {
jt = this.getJdbcTemplate();
}
@Override
public void insertStudent(Student student) {
String sql = “insert into student(name,age) value(?,?)”;
this.jt.update(sql,student.getName(),student.getAge()) ;
}
Spring的事务管理:
原子性: server层调用DAO层 要成功都成功,不成功都不成功
主要是把DAO层提升到server层
Spring中通常可以通过三种方式通过以下三种方法实现对事务的管理:
事务属于系统级服务,将来作为切面出现,把需要做的操作织入到主业务中,切入点实际上就是server层的方法,只要指定了切入点,又指定了切面(事务),就可以把事务织入到方法层的server上(系统级方法调用AOP(切面),我们需要给织入主业务,织入点就是主业务的server层)把事务织入到server层的方法上 这就是我们实现的思路
Spring事务管理API:接口
必须保证记住,理解记忆
Spring的回滚方式:默认方式:发生运行时异常时发生回滚(严重),发生受查时异常时提交(编译时异常)
运行时异常虚拟机直接挂掉,受查时异常可以挽救通过捕捉异常 受查异常可以由程序员可以设置其回滚方式
Spring事务定义接口:
oracal的隔离级别 isolation 默认为2 级
MySQL默认的隔离级别是 4级
事务定义了七个事务传播行为常量
此配置文件没有采用事务管理,所以购买股票的时候,出现了数据库中账户金额减少了,但是股票数目没有增加的不一致情况。
下面说一下其中一个demo
首先是整个框架结构
实体类:银行账户 Accoount.java
package com.vrv.yinkailong.bean;//银行账户public class Accoount { private Integer aid; private String aname; //账户名称 private double balance; // 账户余额 public Accoount() { super(); } public Accoount(String aname, double balance) { super(); this.aname = aname; this.balance = balance; } public Integer getAid() { return aid; } public void setAid(Integer aid) { this.aid = aid; } public String getAname() { return aname; } public void setAname(String aname) { this.aname = aname; } public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; } @Override public String toString() { return "Accoount [aid=" + aid + ", aname=" + aname + ", balance=" + balance + "]"; }}
实体类: 股票账户 Stock.java
package com.vrv.yinkailong.bean;//股票账户public class Stock { private Integer sid; private String sname; //股票名称 private int amount; //股票数量 public Stock() { super(); } public Stock(String sname, int amount) { super(); this.sname = sname; this.amount = amount; } public Integer getSid() { return sid; } public void setSid(Integer sid) { this.sid = sid; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } public int getAmount() { return amount; } public void setAmount(int amount) { this.amount = amount; } @Override public String toString() { return "Stock [sid=" + sid + ", sname=" + sname + ", amount=" + amount + "]"; }}
接着是service层: 定义接口 IBuyStockService.java
package com.vrv.yinkailong.service;import com.vrv.yinkailong.exception.BuyStockException;public interface IBuyStockService { //开账户的方法 void openAccouont(String aname,double money); void openStock(String sname,int count); //买股票 void buyStock(String aname,double money,String sname,int count) throws BuyStockException;}
接口的实现
package com.vrv.yinkailong.service;import com.vrv.yinkailong.dao.IAccountDao;import com.vrv.yinkailong.dao.IStockDao;import com.vrv.yinkailong.exception.BuyStockException;public class BuyStockServiceImpl implements IBuyStockService { private IAccountDao ado; private IStockDao idao; //必須要實現set方法 public void setAdo(IAccountDao ado) { this.ado = ado; } public void setIdao(IStockDao idao) { this.idao = idao; } @Override public void openAccouont(String aname, double money) { ado.insertAccount(aname,money); } @Override public void openStock(String sname, int count) { idao.insertStock(sname,count); } @Override public void buyStock(String aname, double money, String sname, int count) throws BuyStockException { Boolean isBuy = true; ado.updateAccount(aname,money,isBuy); //人为的制造异常,然后引出事务 /* if (true) { throw new BuyStockException("购买股票不成功!!!但是钱被扣了"); }*/ idao.updateStock(sname,count,isBuy); }}
增加相应的dao层,因为实现中用到了相应的dao 接口 IAccountDao.java
package com.vrv.yinkailong.dao;public interface IAccountDao { void insertAccount(String aname, double money); void updateAccount(String aname, double money, Boolean isBuy);}
接口 : IStockDao.java
package com.vrv.yinkailong.dao;public interface IStockDao { void insertStock(String sname, int count); void updateStock(String sname, int count, Boolean isBuy);}
DAO接口的实现 AccountDaoImpl.java 需要继承 JdbcDaoSupport
package com.vrv.yinkailong.daoImpl;import org.springframework.jdbc.core.support.JdbcDaoSupport;import com.vrv.yinkailong.dao.IAccountDao;public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao{ @Override public void insertAccount(String aname, double money) { String sql = "insert into account(aname,balance) value(?,?)"; this.getJdbcTemplate().update(sql,aname,money); } @Override public void updateAccount(String aname, double money, Boolean isBuy) { //默认卖股票 //尤其需要主要sql里面语句增加和修改是在原字段基础上进行的修改,切勿写错了 balance String sql = "update account set balance=balance+? where aname=?"; if (isBuy) { //此处为买入股票增加股票数量 sql = "update account set balance=balance-? where aname=?"; } this.getJdbcTemplate().update(sql,money,aname); }}
DAO层的实现 StockDaoImpl.java 同理需要继承JdbcDaoSupport
package com.vrv.yinkailong.daoImpl;import org.springframework.jdbc.core.support.JdbcDaoSupport;import com.vrv.yinkailong.dao.IStockDao;public class StockDaoImpl extends JdbcDaoSupport implements IStockDao { @Override public void insertStock(String sname, int count) { String sql = "insert into stock(sname,amount) value(?,?)"; this.getJdbcTemplate().update(sql,sname,count); } @Override public void updateStock(String sname, int count, Boolean isBuy) { //默认卖股票 String sql = "update stock set amount=amount-? where sname=?"; if (isBuy) { //此处为买入股票增加股票数量 sql = "update stock set amount=amount+? where sname=?"; } this.getJdbcTemplate().update(sql,count,sname); }}
下面是主配置文件 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" 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"> <!-- -指定读取配置文件路径 加上context约束必须引入相应的头文件 常用方式context约束--> <context:property-placeholder location="classpath:jdbc.properties"/> <!-- -注册数据源--> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/curd"/> <property name="user" value="root"/> <property name="password" value="123456"/> </bean> <!-- 指定读取配置文件路径 加上context约束必须引入相应的头文件 常用方式context约束 任意选其中一种方法即可--> <!-- <context:property-placeholder location="classpath:jdbc.properties"/> <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.user}"/> <property name="password" value="${jdbc.password}"/> </bean> --> <bean id="IAccountdao" class="com.vrv.yinkailong.daoImpl.AccountDaoImpl"> <property name="dataSource" ref="dataSource"/> </bean> <bean id="IStockdao" class="com.vrv.yinkailong.daoImpl.StockDaoImpl"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 注册Service --> <bean id="BuyStockService" class="com.vrv.yinkailong.service.BuyStockServiceImpl"> <property name="ado" ref="IAccountdao"/> <property name="idao" ref="IStockdao"/> </bean></beans>
使用的jdbc.properties 配置文件
jdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://127.0.0.1:3306/curdjdbc.user=rootjdbc.password=123456
然后是测试类 MyTest.java
package com.vrv.yinkailong.test;import org.junit.Before;import org.junit.Test;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.vrv.yinkailong.exception.BuyStockException;import com.vrv.yinkailong.service.IBuyStockService;public class MyTest { private IBuyStockService service; @Before public void testBefore() { ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); service = (IBuyStockService) ac.getBean("BuyStockService"); System.out.println("我执行了before()方法"); } @Test public void testOpen() { service.openAccouont("张三", 10000); service.openStock("动力节点", 1); } //需要处理受查 异常 该方法是虚拟机调用 @Test public void testBuyAccount() throws BuyStockException { service.buyStock("张三", 500, "动力节点", 5); }}
此时的执行结果是没问题的
但是我们这里主要学习得是事务处理,很明显在购买股票过程很可能发生异常,需要我们进行处理,这里我们自定义一个异常类 BuyStockException.java
package com.vrv.yinkailong.exception;//买股票过程可能会发生异常 只要继承exception就会发生授权异常,必须进行处理public class BuyStockException extends Exception { public BuyStockException() { super(); } public BuyStockException(String message) { super(message); }}
暂时代码只写到这里,如果还需要继续使用事务来处理异常,需要重新定义主配置文件
此配置文件没有采用事务管理,所以购买股票的时候,出现了数据库中账户金额减少了,但是股票数目没有增加的不一致情况。
使用 Spring 的事务代理工厂管理事务:
该方式是,需要为目标类,即 Service 的实现类创建事务代理。事务代理使用的类是TransactionProxyFactoryBean,该类需要初始化如下一些属性:
(1)transactionManager:事务管理器
(2)target:目标对象,即 Service 实现类对象
(3)transactionAttributes:事务属性设置
对于 XML 配置代理方式实现事务管理时,受查异常的回滚方式,程序员可以通过以下方式进行设置:通过“-异常”方式,可使发生指定的异常时事务回滚;通过“+异常”方式,可使发生指定的异常时事务提交。
明天继续补上!与君共勉,今天由于粗心大意,在数据库方面遇到一些问题,所以进度有点慢,明天继续补上!谢谢观看
- Hibernate学习5 事务管理简单例子购买股票
- hibernate-简单事务管理
- hibernate学习笔记3--事务管理
- Spring 学习笔记 事务管理 解决购买彩票问题
- Spring3.1.3 + Hibernate4 事务管理简单例子
- Spring3.1.3 + Hibernate4 事务管理简单例子
- Spring对Hibernate事务管理的简单理解
- Hibernate 最简单例子
- hibernate 简单例子
- Hibernate的简单例子
- Hibernate简单例子
- Spring+Hibernate 简单例子
- Hibernate的简单例子
- 一个简单的学习spring+hibernate的例子
- 菜鸟学习Hibernate——简单的一个例子
- Hibernate的学习一__简单的小例子
- Hibernate学习笔记——Introduction和简单例子
- 菜鸟学习Hibernate——简单的一个例子
- 3.列表(一个打了激素的数组)
- (3)window事件、广告弹出
- 面向过程简单的五子棋逻辑
- python求解括号匹配的相关问题
- ACM训练日记—8月5日
- Hibernate学习5 事务管理简单例子购买股票
- Cocos2d-x实战项目开发:运动的小球
- javascript 实现父节点下子节点的倒序排列
- PYTHON机器学习实战——朴素贝叶斯
- Dream City ZOJ
- sstream与相比stdio.h的好处
- java mooc第三周对象容器
- Are We There Yet? (zoj1745)
- 用C++写一个日历程序,要求输入年份,显示全年的日历