————吾亦无他,唯手熟尔,谦卑若愚,好学若饥————-
股票买卖案例(我会用三种开启事物的方法 代理工厂bean版的,注解版的,aspectj xml版的)
简单的介绍一下这个小例子,就是俩个表,一个就是你的账户表,一张就是你的股票的表
一切从简,写
的简单一点(你可以看成有很多不严谨的地方,只是一个Spring中的事务的简单使用,仅供理解事务,不用想太多)
之前的那些jar包就不说了,从案例开始
01.数据库准备:
01.1账户表Account
01.2股票表Stock
02.IDEA中分层开发:
02.1实体类(前面俩个实体类可以说在这个例子里没有用到,但是这是一种习惯)
StockInfo表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 1package cn.dawn.day22tx.entity;
2
3/**
4 * Created by Dawn on 2018/3/15.
5 */
6public class StockInfo {
7 private Integer sid;
8 private String sname;
9 private Integer scount;
10
11 public Integer getSid() {
12 return sid;
13 }
14
15 public void setSid(Integer sid) {
16 this.sid = sid;
17 }
18
19 public String getSname() {
20 return sname;
21 }
22
23 public void setSname(String sname) {
24 this.sname = sname;
25 }
26
27 public Integer getScount() {
28 return scount;
29 }
30
31 public void setScount(Integer scount) {
32 this.scount = scount;
33 }
34}
35
AccountInfo表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 1package cn.dawn.day22tx.entity;
2
3/**
4 * Created by Dawn on 2018/3/15.
5 */
6public class AccountInfo {
7 private Integer aid;
8 private String aname;
9 private Integer ablance;
10
11 public Integer getAid() {
12 return aid;
13 }
14
15 public void setAid(Integer aid) {
16 this.aid = aid;
17 }
18
19 public String getAname() {
20 return aname;
21 }
22
23 public void setAname(String aname) {
24 this.aname = aname;
25 }
26
27 public Integer getAblance() {
28 return ablance;
29 }
30
31 public void setAblance(Integer ablance) {
32 this.ablance = ablance;
33 }
34}
35
StockException类
1
2
3
4
5
6
7
8
9
10
11
12
13
14 1package cn.dawn.day22tx.entity;
2
3/**
4 * Created by Dawn on 2018/3/15.
5 */
6public class StockException extends ClassNotFoundException {
7 public StockException() {
8 }
9
10 public StockException(String s) {
11 super(s);
12 }
13}
14
这个类有点要说的,Spring的事务中执行一半遇到异常怎么操作?默认情况下是运行异常会回滚/受查异常会提交这执行过的代码,所以我做了个受查异常,一会可以测试一下
02.2dao层,一个对股票表操作,一个对账户表操作
IStockDAO股票接口
1
2
3
4
5
6
7
8
9 1package cn.dawn.day22tx.dao;
2
3/**
4 * Created by Dawn on 2018/3/15.
5 */
6public interface IStockDAO {
7 public boolean updateStock(int sid,int scount,boolean isBuy);
8}
9
StockDAOImpl股票接口的实现类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 1package cn.dawn.day22tx.dao;
2
3import org.springframework.jdbc.core.support.JdbcDaoSupport;
4
5/**
6 * Created by Dawn on 2018/3/15.
7 */
8public class StockDAOImpl extends JdbcDaoSupport implements IStockDAO {
9 public boolean updateStock(int sid, int scount, boolean isBuy) {
10 String sql="";
11 boolean flag=false;
12 if (isBuy){
13 //买股票
14 sql="update stock set scount=scount+? where sid=?";
15 }else {
16 sql="update stock set scount=scount-? where sid=?";
17 }
18 int result = this.getJdbcTemplate().update(sql,scount,sid);
19 if (result>0) {
20 flag = true;
21 }
22 return flag;
23 }
24}
25
这儿我将isBuy的布尔变量当等于true的时候,进行买股票操作,你的股票表上的股票股数增加
IAccountDAO账户接口
1
2
3
4
5
6
7
8
9 1package cn.dawn.day22tx.dao;
2
3/**
4 * Created by Dawn on 2018/3/15.
5 */
6public interface IAccountDAO {
7 public boolean updateAccount(int aid,int ablance,boolean isBuy);
8}
9
AccountDAOImpl账户的实现类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 1package cn.dawn.day22tx.dao;
2
3import org.springframework.jdbc.core.support.JdbcDaoSupport;
4
5/**
6 * Created by Dawn on 2018/3/15.
7 */
8public class AccountDAOImpl extends JdbcDaoSupport implements IAccountDAO {
9 public boolean updateAccount(int aid, int ablance, boolean isBuy) {
10 String sql="";
11 boolean flag=false;
12 if(isBuy){
13 //买股票
14 sql="update account set ablance=ablance-? where aid=?";
15 }else {
16 sql="update account set ablance=ablance+? where aid=?";
17 }
18 int count = this.getJdbcTemplate().update(sql, ablance, aid);
19 if(count>0){
20 flag=true;
21 }
22 return flag;
23 }
24}
25
02.3service层
股票的交易接口IStockPayService
1
2
3
4
5
6
7
8
9
10
11 1package cn.dawn.day22tx.service;
2
3import cn.dawn.day22tx.entity.StockException;
4
5/**
6 * Created by Dawn on 2018/3/15.
7 */
8public interface IStockPayService {
9 public boolean buyStock(int aid,int ablance,int sid,int scount) throws StockException;
10}
11
股票交易的实现类StockPayServiceImpl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 1package cn.dawn.day22tx.service;
2
3import cn.dawn.day22tx.dao.IAccountDAO;
4import cn.dawn.day22tx.dao.IStockDAO;
5import cn.dawn.day22tx.entity.StockException;
6import org.springframework.transaction.annotation.Transactional;
7
8/**
9 * Created by Dawn on 2018/3/15.
10 */
11public class StockPayServiceImpl implements IStockPayService {
12 IStockDAO iStockDAO;
13 IAccountDAO iAccountDAO;
14 //@Transactional(rollbackFor = StockException.class)
15 public boolean buyStock(int aid, int ablance, int sid, int scount) throws StockException {
16 boolean isBuy=true;
17 boolean sflag = iStockDAO.updateStock(sid, scount, isBuy);
18
19 if(true){
20 throw new StockException("网络被挂掉异常");
21 }
22
23 boolean aflag = iAccountDAO.updateAccount(aid, ablance, isBuy);
24
25 if(sflag&&aflag)
26 return true;
27 else
28 return false;
29 }
30
31 public IStockDAO getiStockDAO() {
32 return iStockDAO;
33 }
34
35 public void setiStockDAO(IStockDAO iStockDAO) {
36 this.iStockDAO = iStockDAO;
37 }
38
39 public IAccountDAO getiAccountDAO() {
40 return iAccountDAO;
41 }
42
43 public void setiAccountDAO(IAccountDAO iAccountDAO) {
44 this.iAccountDAO = iAccountDAO;
45 }
46}
47
看到那个方法上面注释掉的那个注解了吗?那是第二种方式要用到,只有在第二种方式注解版的时候才用到,其他俩种方式就注释掉它,免得有干扰,切记,用的时候把注释消掉,不用就注释它
@Transactional里面我只写了遇到什么异常会回滚,它的传播行为和隔离级别有默认值,我就省略了
03.xml的配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 1<?xml version="1.0" encoding="UTF-8"?>
2<beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xmlns:aop="http://www.springframework.org/schema/aop"
5 xmlns:p="http://www.springframework.org/schema/p"
6 xmlns:context="http://www.springframework.org/schema/context"
7 xmlns:tx="http://www.springframework.org/schema/tx"
8 xsi:schemaLocation="http://www.springframework.org/schema/beans
9 http://www.springframework.org/schema/beans/spring-beans.xsd
10 http://www.springframework.org/schema/aop
11 http://www.springframework.org/schema/aop/spring-aop.xsd
12 http://www.springframework.org/schema/context
13 http://www.springframework.org/schema/context/spring-context.xsd
14 http://www.springframework.org/schema/tx
15 http://www.springframework.org/schema/tx/spring-tx.xsd">
16
17 <!--配置jdbc。properties-->
18 <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
19
20
21 <!--阿里的Druid-->
22 <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
23 <property name="driverClassName" value="${jdbc.driver}"></property>
24 <property name="url" value="${jdbc.url}"></property>
25 <property name="username" value="${jdbc.username}"></property>
26 <property name="password" value="${jdbc.password}"></property>
27 </bean>
28
29
30 <!--dao层-->
31 <bean id="stockDAO" class="cn.dawn.day22tx.dao.StockDAOImpl">
32 <property name="dataSource" ref="dataSource"></property>
33 </bean>
34 <bean id="accountDAO" class="cn.dawn.day22tx.dao.AccountDAOImpl">
35 <property name="dataSource" ref="dataSource"></property>
36 </bean>
37
38 <!--service-->
39 <bean id="stockpPayService" class="cn.dawn.day22tx.service.StockPayServiceImpl">
40 <property name="iAccountDAO" ref="accountDAO"></property>
41 <property name="iStockDAO" ref="stockDAO"></property>
42 </bean>
43
44 <!--事务管理器-->
45 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
46 <property name="dataSource" ref="dataSource"></property>
47 </bean>
48 <!--第三种方式 aspectj xml版-->
49 <tx:advice id="txadvice" transaction-manager="transactionManager">
50 <tx:attributes>
51 <tx:method name="buyStock" isolation="DEFAULT" propagation="REQUIRED" rollback-for="StockException"/>
52 </tx:attributes>
53 </tx:advice>
54 <aop:config>
55 <aop:pointcut id="mypointccut" expression="execution(* *..day22tx.service.*.*(..))"></aop:pointcut>
56 <aop:advisor advice-ref="txadvice" pointcut-ref="mypointccut"></aop:advisor>
57 </aop:config>
58
59 <!--第二种事务开启方式,注解版-->
60 <!--<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>-->
61
62 <!--第一种事务开启方式代理工厂-->
63 <!--<bean id="txService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
64 <property name="transactionManager" ref="transactionManager"></property>
65 <property name="target" ref="stockpPayService"></property>
66 <property name="transactionAttributes">
67 <props>
68 <prop key="buyStock">ISOLATION_DEFAULT,PROPAGATION_REQUIRED,-StockException</prop>
69 </props>
70 </property>
71 </bean>-->
72</beans>
73
没什么需要说的,这儿像什么命名空间等需要注意一点,其他的就是照猫画虎
有什么不清楚的评论留言,我会帮忙解决
04.单测方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68 1package cn.dawn.day22tx;
2
3
4import cn.dawn.day22tx.entity.StockException;
5import cn.dawn.day22tx.service.IStockPayService;
6import org.junit.Test;
7import org.springframework.context.ApplicationContext;
8import org.springframework.context.support.ClassPathXmlApplicationContext;
9
10import java.util.List;
11
12/**
13 * Created by Dawn on 2018/3/3.
14 */
15public class test20180315 {
16 @Test
17 /*aspectj xml方式*/
18 public void t03() {
19 ApplicationContext context=new ClassPathXmlApplicationContext("ApplicationContext-day22tx.xml");
20 IStockPayService service = (IStockPayService) context.getBean("stockpPayService");
21 boolean flag = false;
22 try {
23 flag = service.buyStock(1, 100, 1, 20);
24 } catch (StockException e) {
25 e.printStackTrace();
26 }
27 if(flag){
28 System.out.println("购买成功");
29 }
30
31 }
32
33
34 @Test
35 /*注解方式*/
36 public void t02() {
37 ApplicationContext context=new ClassPathXmlApplicationContext("ApplicationContext-day22tx.xml");
38 IStockPayService service = (IStockPayService) context.getBean("stockpPayService");
39 boolean flag = false;
40 try {
41 flag = service.buyStock(1, 100, 1, 20);
42 } catch (StockException e) {
43 e.printStackTrace();
44 }
45 if(flag){
46 System.out.println("购买成功");
47 }
48
49 }
50
51 @Test
52 /*代理工厂bean的方式*/
53 public void t01() {
54 ApplicationContext context=new ClassPathXmlApplicationContext("ApplicationContext-day22tx.xml");
55 IStockPayService service = (IStockPayService) context.getBean("txService");
56 boolean flag = false;
57 try {
58 flag = service.buyStock(1, 100, 1, 20);
59 } catch (StockException e) {
60 e.printStackTrace();
61 }
62 if(flag){
63 System.out.println("购买成功");
64 }
65
66 }
67}
68
简述一下运行结果,单测成功,中途会打印异常信息,由于开启了事务,同生共死,俩张表在数据库都没有改变值,事务的出口被回滚了