zoukankan      html  css  js  c++  java
  • spring boot学习(6) SpringBoot 之事务管理

    两个操作要么同时成功,要么同时失败;
    事务的一致性;
    以前学ssh ssm都有事务管理service层通过applicationContext.xml配置,所有service方法都加上事务操作;

    用来保证一致性,即service方法里的多个dao操作,要么同时成功,要么同时失败;

    下面模拟用户转账,a用户转账给b用户200元;需要事务管理;
    项目结构:
     
    1.代码:                    
    com.cy.entity.Account.java;
    package com.cy.entity;
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.Table;
    
    /**
     * 账户实体
     * @author CY
     *
     */
    @Entity
    @Table(name="t_account")
    public class Account {
        
        @Id
        @GeneratedValue
        private Integer id;
        
        @Column(length=50)
        private String userName;
        
        private float balance;    //余额
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
        public float getBalance() {
            return balance;
        }
    
        public void setBalance(float balance) {
            this.balance = balance;
        }
        
        
        
    }

    账户dao接口:com.cy.dao.AccountDao.java:

    package com.cy.dao;
    
    import org.springframework.data.jpa.repository.JpaRepository;
    import com.cy.entity.Account;
    
    /**
     * 账户Dao接口
     * JpaRepository<T, ID>第二个参数是主键类型
     * @author CY
     *
     */
    public interface AccountDao extends JpaRepository<Account, Integer>{
    
    }

    账户service接口:com.cy.service.AccountService.java:

    package com.cy.service;
    
    /**
     * 账户Service接口
     * @author CY
     *
     */
    public interface AccountService {
        
        /**
         * 从fromUser转账到toUser,account钱;
         * @param fromUser
         * @param toUser
         * @param account
         */
        public void transferAccounts(int fromUser, int toUser, float account);
    }

    账户接口实现类:com.cy.service.impl.AccountServiceImpl.java;

    package com.cy.service.impl;
    
    import javax.annotation.Resource;
    import javax.transaction.Transactional;
    import org.springframework.stereotype.Service;
    import com.cy.dao.AccountDao;
    import com.cy.entity.Account;
    import com.cy.service.AccountService;
    
    /**
     * 账户service实现类
     * @author CY
     *
     */
    @Service("accountService")
    public class AccountServiceImpl implements AccountService{
        
        @Resource
        private AccountDao accountDao;
        
        /**
         * 从A用户转账到B用户account元;
         * 也就是两个操作:
         * A用户减去accout元,B用户加上account元
         */
        @Override
        @Transactional
        public void transferAccounts(int fromUser, int toUser, float account) {
            Account a = accountDao.getOne(fromUser);
            a.setBalance(a.getBalance() - account);
            accountDao.save(a);
            
            Account b = accountDao.getOne(toUser);
            b.setBalance(b.getBalance() + account);
            int i = 1/0;        //这里制造个异常
            accountDao.save(b);
        }
        
    }

    com.cy.controller.AccountController.java来模拟用户转账:

    这里返回json数据格式,成功ok,失败no

    package com.cy.controller;
    
    import javax.annotation.Resource;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import com.cy.service.AccountService;
    
    /**
     * 账户Controller层
     * @author CY
     *
     */
    @RestController
    @RequestMapping("/account")
    public class AccountController {
        
        @Resource
        private AccountService accountService;
        
        @RequestMapping("/transfer")
        public String transferAccount(){
            try{
                accountService.transferAccounts(1, 2, 200);
                return "ok";
            }catch(Exception e){
                return "no";
            }
        }
    }

    2.测试:

    启动项目,查看新建的表t_account:

    mysql> desc t_account;
    +-----------+-------------+------+-----+---------+----------------+
    | Field     | Type        | Null | Key | Default | Extra          |
    +-----------+-------------+------+-----+---------+----------------+
    | id        | int(11)     | NO   | PRI | NULL    | auto_increment |
    | balance   | float       | NO   |     | NULL    |                |
    | user_name | varchar(50) | YES  |     | NULL    |                |
    +-----------+-------------+------+-----+---------+----------------+

    弄点数据:

    mysql> select * from t_account;
    +----+---------+-----------+
    | id | balance | user_name |
    +----+---------+-----------+
    |  1 |     700 | zhangsan  |
    |  2 |     300 | lisi      |
    +----+---------+-----------+

    浏览器http://localhost/account/transfer:

    1)显示no,说明转账失败;

    2)数据库数据,zhangsan仍然是700,lisi仍然是300,保证了数据一致性;

    查看发出的sql:

    Hibernate: select account0_.id as id1_0_0_, account0_.balance as balance2_0_0_, account0_.user_name as user_nam3_0_0_ from t_account account0_ where account0_.id=?
    Hibernate: select account0_.id as id1_0_0_, account0_.balance as balance2_0_0_, account0_.user_name as user_nam3_0_0_ from t_account account0_ where account0_.id=?
    没有执行保存,全部弄完了才保存;

    说明:

    这里使用的是:import javax.transaction.Transactional;(这个是jpa规范)
    使用import org.springframework.transaction.annotation.Transactional也行;(这个spring实现了jpa规范)
  • 相关阅读:
    HTML中一定会常用的标签和标签属性(这是网页构成的重要元素
    HTML(超文本语言)
    SQL SERVER中视图、事务
    important覆盖行内样式
    线性渐变
    「JavaScript面向对象编程指南」闭包
    移动端文章图片大小限制
    Vue中ajax返回的结果赋值
    「JavaScript面向对象编程指南」基础
    JS媒体查询
  • 原文地址:https://www.cnblogs.com/tenWood/p/8644615.html
Copyright © 2011-2022 走看看