美文网首页JavaSE
Spring事务管理---转账案例搭建

Spring事务管理---转账案例搭建

作者: 熊猫读书营 | 来源:发表于2018-04-20 21:17 被阅读1次

    上一篇文章总结了Spring事务管理的相关知识点。接下来写一个模拟银行转账的案例来实际操作一下。

    一、转账环境搭建

    1. 创建数据库表
        CREATE DATABASE spring_transation;
        USE spring_transation;
        CREATE TABLE account (
            id int(11) NOT NULL AUTO_INCREMENT,
            name varchar(20) NOT NULL,
            money double DEFAULT NULL,
            PRIMARY KEY (id)
        )
    
    1. 插入初始数据
        INSERT INTO account VALUES ('1','aaa',1000);
        INSERT INTO account VALUES ('2','bbb',1000);
        INSERT INTO account VALUES ('3','ccc',1000);
    
    1. 创建Spring项目
      使用IDEA,用Maven来构建一个Spring项目。
      参考链接:IDEA搭建Spring项目(Maven版)

    pom.xml文件中引入所需要的依赖:

    <dependencies>
        <!--spring所需依赖-->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-web</artifactId>
          <version>4.3.8.RELEASE</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>4.3.8.RELEASE</version>
        </dependency>
        <!--其他需要的包-->
        <dependency>
          <groupId>org.apache.commons</groupId>
          <artifactId>commons-lang3</artifactId>
          <version>3.4</version>
        </dependency>
        <!--mysql driver-->
        <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>5.1.6</version>
        </dependency>
        <!--jdbc-->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-jdbc</artifactId>
          <version>3.0.5.RELEASE</version>
        </dependency>
        <!--c3p0-->
        <dependency>
          <groupId>com.mchange</groupId>
          <artifactId>c3p0</artifactId>
          <version>0.9.5.1</version>
        </dependency>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.12</version>
        </dependency>
    

    我的项目目录结构如下:

    1. 定义接口方法
      ①新建业务层接口AccountService,定义转账方法
    //转账业务接口
    public interface AccountService {
        public void transfer(String out, String in, Double money);
    }
    

    ②业务层接口实现类

    public class AccountServiceImpl implements AccountService{
      
        @Override
        public void transfer(String out, String in, Double money) {
    
        }
    }
    

    ③新建数据访问层接口AccountDao

    //转账Dao层接口
    public interface AccountDao {
    
        public void outMoney(String out, Double money);
        public void inMoney(String in, Double money);
    
    }
    

    ④Dao接口实现类
    Spring中提供了一个关于jdbc操作的模板类,只需让Dao实现类继承JdbcDaoSupport即可。

    public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
        @Override
        public void outMoney(String out, Double money) {
            
        }
    
        @Override
        public void inMoney(String in, Double money) {
            
        }
    }
    
    1. 加载Bean配置
      修改applicationContext.xml文件:
      ①引入数据库属性文件
        <context:property-placeholder location="classpath:jdbc.properties"/>
    

    ②配置c3po连接池

    <!-- 配置C3P0连接池 -->
        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
            <property name="driverClass" value="${jdbc.driver_class}"/>
            <property name="jdbcUrl" value="${jdbc.connection.url}"/>
            <property name="user" value="${jdbc.connection.username}"/>
            <property name="password" value="${jdbc.connection.password}"/>
        </bean>
    

    ③配置Dao层类

    <!--配置Dao的类-->
        <bean id="accountDao" class="cn.lovebugs.spring.demo.AccountDaoImpl">
            <property name="dataSource" ref="dataSource"/><!--注入连接池,因为DaoImpl类中继承了jdbc模板类,所以这里只要注入连接池就可以获得jdbc模板-->
        </bean>
    

    ④配置业务层类

    <!--配置业务层类-->
        <bean id="accountService" class="cn.lovebugs.spring.demo.AccountServiceImpl">
            <property name="accountDao" ref="accountDao"/>
        </bean>
    
    1. 完善接口方法
      前面已经定义好了转账所需要的方法,也做好了先相关的配置及jdbc模板,接下来只需完善转账方法即可。
      ①完善业务层接口实现类
    public class AccountServiceImpl implements AccountService{
    
        //注入转账的Dao类,xml文件中的<property name="accountDao" ref="accountDao"/>
        private AccountDao accountDao;
    
        //设值注入
        public void setAccountDao(AccountDao accountDao){
            this.accountDao = accountDao;
        }
    
        @Override
        public void transfer(String out, String in, Double money) {
            accountDao.outMoney(out,money);
            accountDao.inMoney(in,money);
        }
    }
    

    ②完善Dao层实现类

    public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
        @Override
        public void outMoney(String out, Double money) {
            String sql = "update account set money = money - ? where name = ?";
            this.getJdbcTemplate().update(sql,money,out);//jdbc模板类执行sql语句
        }
    
        @Override
        public void inMoney(String in, Double money) {
            String sql = "update account set money = money + ? where name = ?";
            this.getJdbcTemplate().update(sql,money,in);
        }
    }
    

    二、测试

    上面已经搭建好了基本的转账环境,接下来进行测试。
    这里额外引入了一个测试相关的jar包:spring-test-3.2.0.RELEASE.jar

    1. 新建测试类,方法如下:
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    import javax.annotation.Resource;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(value = "classpath:applicationContext.xml")
    public class SpringTest {
    
        @Resource(name = "accountService")
        private AccountService accountService;//引入业务类
    
        @Test
        public void test(){
            accountService.transfer("aaa","bbb",200d);
        }
    
    }
    
    1. 运行test()方法,查看数据库结果

    转账成功。

    三、无事务管理造成的问题

    前面所搭建的转账案例是没有进行事务管理的情况下实现的,因此它存在很大地安全隐患。比如a要向b转账200元,当a的账户减少200元后,此时如果程序发生异常被终止,那么b的账户就无法增加200元,这样就造成了数据不一致的问题。

    如下示例:
    在AccountServiceImpl类的transfer()方法中加入一条异常语句

    @Override
        public void transfer(String out, String in, Double money) {
            accountDao.outMoney(out,money);
            int a = 1 / 0; //强制使程序发生异常
            accountDao.inMoney(in,money);
        }
    

    此时再运行test()方法后查看数据库结果

    结果显然发现a的账户减少了200元,但是b的账户并没有改变。
    这就看出了不加事务管理所造成的后果。

    下一篇文章将会写一下如何进行事务处理。



    微信公众号【IT资源社】
    本公众号致力于免费分享全网最优秀的视频资源,学习资料,面试经验等,前端,PHP,JAVA,算法,Python,大数据等等,你想要的这都有,还会分享优质博文,提高你的认知与思维

    IT资源社-QQ交流群:625494093
    要进微信交流群的话加微信:super1319164238
    微信搜索公众号:IT资源社 或者扫描下方二维码直接关注,


    原创文章,转载请注明出处

    相关文章

      网友评论

        本文标题:Spring事务管理---转账案例搭建

        本文链接:https://www.haomeiwen.com/subject/kuqjkftx.html