两个操作要么同时成功,要么同时失败;
事务的一致性;
以前学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规范)

spring boot学习(6) SpringBoot 之事务管理的更多相关文章

  1. Spring Boot学习——数据库操作及事务管理

    本文讲解使用Spring-Data-Jpa操作数据库. JPA定义了一系列对象持久化的标准. 一.在项目中使用Spring-Data-Jpa 1. 配置文件application.properties ...

  2. spring boot中的声明式事务管理及编程式事务管理

    这几天在做一个功能,具体的情况是这样的: 项目中原有的几个功能模块中有数据上报的功能,现在需要在这几个功能模块的上报之后生成一条消息记录,然后入库,在写个接口供前台来拉取消息记录. 看到这个需求,首先 ...

  3. spring框架学习笔记7:事务管理及案例

    Spring提供了一套管理项目中的事务的机制 以前写过一篇简单的介绍事务的随笔:http://www.cnblogs.com/xuyiqing/p/8430214.html 还有一篇Hibernate ...

  4. spring boot学习(十三)SpringBoot缓存(EhCache 2.x 篇)

    SpringBoot 缓存(EhCache 2.x 篇) SpringBoot 缓存 在 Spring Boot中,通过@EnableCaching注解自动化配置合适的缓存管理器(CacheManag ...

  5. spring boot 学习(五)SpringBoot+MyBatis(XML)+Druid

    SpringBoot+MyBatis(xml)+Druid 前言 springboot集成了springJDBC与JPA,但是没有集成mybatis,所以想要使用mybatis就要自己去集成. 主要是 ...

  6. spring boot 学习(十)SpringBoot配置发送Email

    SpringBoot配置发送Email 引入依赖 在 pom.xml 文件中引入邮件配置: <dependency> <groupId>org.springframework. ...

  7. spring boot学习(4) SpringBoot 之Spring Data Jpa 支持(1)

    第一节:Spring Data Jpa 简介 Spring-Data-Jpa JPA(Java Persistence API)定义了一系列对象持久化的标准,目前实现这一规范的产品有Hibernate ...

  8. spring boot学习(2) SpringBoot 项目属性配置

    第一节:项目内置属性 application.properties配置整个项目的,相当于以前的web.xml: 注意到上一节的访问HelloWorld时,项目路径也没有加:直接是http://loca ...

  9. 【Spring Boot学习之五】切面日志管理

    环境 eclipse 4.7 jdk 1.8 Spring Boot 1.5.2 一.log4j 常见方式:log4j.properties + org.apache.log4j.Logger比如:l ...

随机推荐

  1. struts2 实现rest

    参考链接https://www.ibm.com/developerworks/cn/java/j-lo-struts2rest/

  2. Struts2工作原理及流程

    Struts2是基于MVC设计模式的JavaWeb 框架技术. 基于Struts2开发Java Web项目的主要步骤如下: (1)在web.xml中配置FilterDispatcher. (2)设计和 ...

  3. hibernate 各种主键生成策略(转)

    http://www.cnblogs.com/kakafra/archive/2012/09/16/2687569.html 1.assigned 主键由外部程序负责生成,在 save() 之前必须指 ...

  4. 在vmware中实现Ubuntu与win7(主机)之间同步实现共享文件

    作为linux的热衷者和初学者,我们在学习的过程中难免会碰到不少的问题,下面简单的介绍和总结一下,我是如何通过以下两种方法解决在vmware中实现Ubuntu与win7(主机)之间同步实现共享文件的. ...

  5. PyCharm 注释

    1.1 单行注释(行注释) 语法格式: #[空格]说明性文字信息 注:可放一行代码的后面进行说明 添加快捷键:  Ctrl+/ 取消快捷键:  同上 1.2 多行注释(块注释) 语法格式: " ...

  6. Python高手之路 ------读书有感

    最近忙中偷闲把前些年买的<Python高手之路>翻了出来,大致看完了一遍,其中很多内容并不理解,究其原因应该是实践中的经验不足,而这对于现如今的我仍是难以克服的事情,对此也就只能说是看会了 ...

  7. 【c++基础】int转string自动补零

    前言 使用to_string函数可以将不同类型的数据转换为string类,请参考here和here.如果string的位数固定,如何进行自动补零呢?请看本文实例! 代码 确定位数,to_string ...

  8. for-auto使用

    前言 c++11新增了一个工具,让编译器能够根据初始值的类型推断变量的类型: c++11还新增了一种循环,基于范围的for循环,可以对数组或者容器类的每一个元素执行相同的操作:同时,可以使用& ...

  9. MyEclipse多次重装、删除注册表、重装系统激活都不成功,终极解决方法 - imsoft.cnblogs

      问题:注册成功的MyEclipse被修改了一个配置文件之后,激活失败,然后在网上找激活码,激活不成功,但激活文件一直保存在电脑中,每次打开MyEclipse的激活界面总看得到之前的激活码.后面尝试 ...

  10. Robot Framework 自定义库

    进入  python安装路径\Lib\site-packages 创建文件夹,库名 创建py文件,myclass.py 创建py文件,__init__.py 导入自定义库 遇到的问题: python版 ...