SSM-Spring-21:Spring中事物的使用案例

释放双眼,带上耳机,听听看~!

 

 

 

————吾亦无他,唯手熟尔,谦卑若愚,好学若饥————-

 

 

股票买卖案例(我会用三种开启事物的方法 代理工厂bean版的,注解版的,aspectj xml版的)

简单的介绍一下这个小例子,就是俩个表,一个就是你的账户表,一张就是你的股票的表

一切从简,写
的简单一点(你可以看成有很多不严谨的地方,只是一个Spring中的事务的简单使用,仅供理解事务,不用想太多)

之前的那些jar包就不说了,从案例开始

 

01.数据库准备:

01.1账户表Account

SSM-Spring-21:Spring中事物的使用案例

01.2股票表Stock

SSM-Spring-21:Spring中事物的使用案例

 

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

简述一下运行结果,单测成功,中途会打印异常信息,由于开启了事务,同生共死,俩张表在数据库都没有改变值,事务的出口被回滚了

 

给TA打赏
共{{data.count}}人
人已打赏
安全技术

C/C++内存泄漏及检测

2022-1-11 12:36:11

安全经验

Python 3.5.5 和 Python 3.4.8 发布,安全修复版本

2018-2-6 11:12:22

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索