需求介绍

熟悉事务管理。

什么是事务

  事务是由N步数据库操作序列组成的逻辑执行单元,这系列操作要么全执行,要么全放弃执行。

事务的特性(ACID)

  • 原子性(Atomicity):事务是应用中不可再分的最小执行体。
  • 一致性(Consistency):事务执行的结果,须使数据从一个一致性状态,变为另一个一致性状态。
  • 隔离性(Isolation):各个事务的执行互不干扰,任何事务的内部操作对其他的事务都是隔离的。
  • 持久性(Durability):事务一旦提交,对数据所做的任何改变都要记录到永久存储器中。

事务的隔离性

常见的并发异常

  • 第一类丢失更新、第二类丢失更新。
  • 脏读、不可重复读、幻读。

常见的隔离级别

  • Read Uncommitted:读取未提交的数据。
  • Read Committed:读取已提交的数据。
  • Repeatable Read:可重复读。
  • Serializable:串行化。

实现机制

悲观锁(数据库)

共享锁(S锁) 事务A对某数据加了共享锁后,其他事务只能对该数据加共享锁,但不能加排他锁。

排他锁(X锁) 事务A对某数据加了排他锁后,其他事务对该数据既不能加共享锁,也不能加排他锁。

乐观锁(自定义)

版本号、时间戳等 在更新数据前,检查版本号是否发生变化。若变化则取消本次更新,否则就更新数据(版本号+1)。

Spring事务管理

声明式事务

  • 通过XML配置,声明某方法的事务特征。
  • 通过注解,声明某方法的事务特征。

编程式事务

  • 通过 TransactionTemplate 管理事务, 并通过它执行数据库的操作。

代码实现

  首先模拟某一个业务,利用事务实现,首先我们要确定我们的业务要写在 Service 业务层,所以在 AlphaService 文件里面编写,我们先考虑一个事务,比方说我们注册一个用户增加一个 user,并且自动的用这个 user 的账号发个帖。那么这一个业务包含两个增加操作。

@Autowired
private UserMapper userMapper; @Autowired
private DiscussPostMapper discussPostMapper; /**
* 通过注解声名某方法的事务特征, 管理事务
*/ /**
* isolation : 隔离级别
* propagation : 传播机制
* @return
*/
// REQUIRED: 支持当前事务(外部事务),如果不存在则创建新事务.
// REQUIRES_NEW: 创建一个新事务,并且暂停当前事务(外部事务).
// NESTED: 如果当前存在事务(外部事务),则嵌套在该事务中执行(独立的提交和回滚),否则就会REQUIRED一样.
@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
public Object save1() {
// 新增用户
User user = new User();
user.setUsername("alpha");
user.setSalt(CommunityUtil.generateUUID().substring(0, 5));
user.setPassword(CommunityUtil.md5("123" + user.getSalt()));
user.setEmail("alpha@qq.com");
user.setHeaderUrl("http://image.nowcoder.com/head/99t.png");
user.setCreateTime(new Date());
userMapper.insertUser(user); // 新增帖子
DiscussPost post = new DiscussPost();
post.setUserId(user.getId());
post.setTitle("Hello");
post.setContent("新人报道!");
post.setCreateTime(new Date());
discussPostMapper.insertDiscussPost(post); // 事务出现异常,会中断回滚
Integer.valueOf("abc"); return "ok";
} /**
* 通过transactionTemplate 管理事务
*/
public Object save2() {
transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); return transactionTemplate.execute(new TransactionCallback<Object>() {
@Override
public Object doInTransaction(TransactionStatus status) {
// 新增用户
User user = new User();
user.setUsername("beta");
user.setSalt(CommunityUtil.generateUUID().substring(0, 5));
user.setPassword(CommunityUtil.md5("123" + user.getSalt()));
user.setEmail("beta@qq.com");
user.setHeaderUrl("http://image.nowcoder.com/head/999t.png");
user.setCreateTime(new Date());
userMapper.insertUser(user); // 新增帖子
DiscussPost post = new DiscussPost();
post.setUserId(user.getId());
post.setTitle("你好");
post.setContent("我是新人!");
post.setCreateTime(new Date());
discussPostMapper.insertDiscussPost(post); Integer.valueOf("abc"); return "ok";
}
});
}

  

然后新建一个测试类,测试我们的方法。

package com.nowcoder.community;

import com.nowcoder.community.service.AlphaService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = CommunityApplication.class)
public class TransactionTests { @Autowired
private AlphaService alphaService; @Test
public void testSave1() {
Object obj = alphaService.save1();
System.out.println(obj);
} @Test
public void testSave2() {
Object obj = alphaService.save2();
System.out.println(obj);
}
}

  

结果会报错,查数据库我们也会看到这个数据是没有插到数据库里面。

  

SpringBoot开发十七-事务管理的更多相关文章

  1. Java EE开发课外事务管理平台

    Java EE开发课外事务管理平台 演示地址:https://ganquanzhong.top/edu 说明文档 一.系统需求 目前课外兴趣培训学校众多,完善,但是针对课外兴趣培训学校教务和人事管理信 ...

  2. SpringBoot(十):SpringBoot的简单事务管理

    SpringBoot集成Mybatis之后,进行事务管理.SpringBoot使用事务非常简单,底层依然采用的是Spring本身提供的事务. 1.在入口类中使用注解@EnableTransaction ...

  3. SpringBoot开发八-会话管理

    需求介绍-会话管理 利用Cookie和Seesion使得HTTP变成有会话的连接,写几个实例演示一下 代码实现 先写个例子,表示客户端第一次访问服务器,服务器端创建一个Cookie发送给客户端. 不管 ...

  4. springboot xml声明式事务管理方案

    在开发过程中springboot提供的常见的事务解决方案是使用注解方式实现. 使用注解 在启动类上添加注解 @EnableTransactionManagement 在需要事务控制的方法添加@Tran ...

  5. Springboot下事务管理的简单使用

    关于事务管理的概念这里就不多介绍了,在我的博客“JDBC事务之理论篇”中也有介绍. 关于Spring的事务管理,主要是通过事务管理器来进行的.这里看个Spring事务管理的接口图:(来自博客https ...

  6. Spring3 (事务管理)

    简介: 1.事务管理.2.整合Junit.3.整和Web 1       事务管理 1.1   回顾事务 l  事务:一组业务操作ABCD,要么全部成功,要么全部不成功. l  特性:ACID 原子性 ...

  7. 跟我学Spring3(9.2):Spring的事务之事务管理器

    原文出处: 张开涛9.2.1 概述 Spring框架支持事务管理的核心是事务管理器抽象,对于不同的数据访问框架(如Hibernate)通过实现策略接口PlatformTransactionManage ...

  8. springbootdruidmybatismysql多数据源事务管理

    springboot+druid+mybatis+mysql+多数据源事务管理 分布式事务在java中的解决方案就是JTA(即Java Transaction API):springboot官方提供了 ...

  9. springboot(二)整合mybatis,多数据源和事务管理

     -- 1.整合mybatis -- 2.整合多数据源 -- 3. 整合事务 代码地址:https://github.com/showkawa/springBoot_2017/tree/master/ ...

随机推荐

  1. MPP大规模并行处理架构详解

    面试官:说下你知道的MPP架构的计算引擎? 这个问题不少小伙伴在面试时都遇到过,因为对MPP这个概念了解较少,不少人都卡壳了,但是我们常用的大数据计算引擎有很多都是MPP架构的,像我们熟悉的Impal ...

  2. 资源:jenkins下载路径

    Jenkins版本下载路径 所有版本:http://mirrors.jenkins.io/war/

  3. 常见链表操作-链表中环的检测(JAVA实现)

    问题如何检测一个单链表中是否有环,例如下图的例子. 解决思路1:快慢指针法这是最常见的方法.思路就是有两个指针P1和P2,同时从头结点开始往下遍历链表中的所有节点. P1是慢指针,一次遍历一个节点.P ...

  4. spring集成flyway

    最近给公司项目集成flyway,由于我们项目移动端使用的是spring框架,网上看了很多博客,感觉这方面的东西还是很少的,毕竟现在是springboot的天下,大多数都是springboot集成fly ...

  5. jenkins报错The goal you specified requires a project to execute but there is no POM inthis directory

    报错截图及详细:   15:30:29[ERROR]The goal you specified requires a project to execute but there is no POM i ...

  6. 短信链接点击跳转到微信小程序

    短信轰炸的时代,之前链接都是跳转到网页的,后来发现粘性不强,再次唤醒用户成本较高,但小程序的订阅功能,再次唤醒成本较低,还便于给用户通知结果.所以现在链接都改跳转到小程序了.废话不多说,现在就看看是如 ...

  7. final修饰符(7)-缓存实例的不可变类

    不可变类的实例状态不可改变,可以很方便地被多个对象所共享,可以考虑缓存这种不可变类的实例

  8. [010] - JavaSE面试题(十):集合之Map

    第一期:Java面试 - 100题,梳理各大网站优秀面试题.大家可以跟着我一起来刷刷Java理论知识 [010] - JavaSE面试题(十):集合之Map 第1问:HashMap和HashTable ...

  9. CentOS更换网易yum源

    最新内容和地址参见http://mirrors.163.com/.help/centos.html 1 首先备份/etc/yum.repos.d/CentOS-Base.repo mv /etc/yu ...

  10. static能修饰什么

    简洁易懂讲清原理,讲不清你来打我~ 修饰普通变量,修改变量的存储区域和生命周期,使变量存储在静态区,在main函数运行前就分配空间,有初始值就初始值,没有初始值就系统默认值初始化 修饰普通函数,修改函 ...