IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 【SpringBoot学习】07、事务管理 -> 正文阅读

[大数据]【SpringBoot学习】07、事务管理

1 事务

【数据库入门】动力节点mysql入门基础03有关于事务的概述

1.1 概述

在这里插入图片描述
事务可以保证多个操作原子性,要么全成功,要么全失败。对于数据库来说事务保证批量的 DML 要么全成功,要么全失败。事务具有四个特征 ACID

  • 原子性( Atomicity)
    整个事务中的所有操作,必须作为一个单元全部完成(或全部取消)。
  • 一致性( Consistency)
    所有事务要求,在同一个事务当中,所有操作必须同时成功,或者同时失败,以保证数据的一致性。
    比方说A转给B 100块,A的账户必然减少100块,B的账户必然增加100块。如果A给B转了100之后系统宕机,A减少100块,B却没有增加100块,这就是数据的不一致性。有点类似于物质守恒。
  • 隔离性(Isolation)
    一个事务不会影响其他事务的运行。
  • 持久性(Durability)
    在事务完成以后,该事务对数据库所作的更改将持久地保存在数据库之中,并不会被回滚

1.2 事务的隔离级别

1.2.1 并发异常

? 当多个客户端并发地访问同一个表时,可能出现下面的一致性问题:

  • 脏读取( Dirty Read)
    一个事务开始读取了某行数据,但是另外一个事务已经更新了此数据但没有能够及时提交,这就出现了脏读取。
    在这里插入图片描述

  • 不可重复读( Non-repeatable Read)
    在同一个事务中,同一个读操作对同一个数据的前后两次读取产生了不同的结果,这就是不可重复读。
    在这里插入图片描述

  • 幻像读( Phantom Read)
    幻像读是指在同一个事务中以前没有的行,由于其他事务的提交而出现的新行。
    在这里插入图片描述

  • 第一类丢失更新
    某一个事务的回滚,导致另外一个事务已经更新的数据丢失了
    在这里插入图片描述

  • 第二类丢失更新
    某一个事务的提交,导致另外一个事务已经更新的数据丢失了
    在这里插入图片描述

1.2.2 四个隔离级别

InnoDB 实现了四个隔离级别,用以控制事务所做的修改,并将修改通告至其它并发的事务:

  • 读未提交( READ UMCOMMITTED) 没有提交就读到了
    导致了:脏读
  • 读已提交( READ COMMITTED) 提交之后才能读到
    解决了:脏读
    导致了:不可重复读
    在事务开启之后,第一次读到的数据是3条,当前事务还没有结束,可能第二次再读取的时候,读到的数据是4条,3不等于4,称为不可重复读取。
  • 可重复读( REPEATABLE READ) 提交之后也读不到,永远读取的都是刚开启事务时的数据
    该隔离级别为 InnoDB 的缺省设置。mysql中默认的事务隔离级别就是这个
    解决了:不可重复读
    导致了:幻读
    早晨9点开始开启了事务,只要事务不结束,到晚上9点,读到的数据还是那样。读到的是假象。不够绝对的真实。
  • 串行化( SERIALIZABLE) 【序列化】
    这是最高隔离级别,效率最低。解决了所有的问题。这种隔离级别表示事务排队不能并发。每一次读取到的数据都是最真实的,并且效率是最低的。
    在这里插入图片描述
    在这里插入图片描述

1.3 隔离实现机制

在这里插入图片描述

1.3.1 悲观锁

悲观锁是数据库自带的
悲观锁看待事情比较悲观,认为如果并发就一定会有问题,既然一定会有问题就要提前对数据加锁

共享锁(S锁)

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

加了共相锁之后只能读数据,不能改数据

排他锁(X锁)

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

加了排他锁既可以读又可以改

1.3.2 乐观锁

乐观锁需要自己定义
乐观锁看待事情比较乐观,认为即使并发了也不会有问题,假设它不会有问题,该读读该写写。当读取数据计算完了需要更改数据的时候,检查数据是否发生更改。如果数据发生更改,说明处理过程中有人改过数据,那就放弃这次操作;否则没人改就提交数据

怎么识别数据变没变?
一个表加上一个字段,或者是时间戳,或者是版本号
任何人更新数据之前检查时间戳或者版本号变没变,如果变了就放弃本次更新,如果没变就提交更新,修改时间戳或者版本号

2 Spring事务管理

在这里插入图片描述
官网文档:https://docs.spring.io/spring-framework/docs/current/reference/html/data-access.html#spring-data-tier
链接可能会失效,可按如下顺序找到:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Spring对任何数据库做事务管理时,API都是统一的
具体来说有两种管理事务的方法

1.声明式事务:不需要写逻辑,只需要在xml配置文件里或者通过注解在方法上做配置就可以使用

2.编程式事务:需要编程,需要用到Transaction Template这个类

两种管理事务的方式,平时优先选第一种,简单;如果要处理的业务比较复杂,只有中间一小部分的事务想管理,就用第二种

2.1 声明式事务

demo是模拟某一个业务,所以把代码写在业务层

杜撰一个需求:注册用户之后自动给用户发一个帖子:新人报到。一个业务完成了两个新增操作(新增用户和新增帖子),要保证业务的事务性

2.1.1 Service示例代码

@Service
public class DemoService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private DiscussPostMapper discussPostMapper;


    //isolation = Isolation.READ_COMMITTED:隔离级别是:读已提交
    //propagation传播机制 a调用b
    //REQUIRED 支持当前事务a,如果不存在,就创建新事务b
    //REQUIRES_NEW 创建新事务b且暂停当前事务
    //NESTED 如果当前存在事务a,则嵌套在该事务a中执行(b有独立的提交和回滚);否则和REQUIRED一样
    @Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)

    public Object demo(){
        //新增用户
        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("hi");
        post.setCreateTime(new Date());
        discussPostMapper.insertDiscussPost(post);

        //人为造错,看数据能不能回滚
        Integer.valueOf("abc");


        return "ok";
    }
}

2.1.2 测试

@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = CommunityApplication.class)
public class TransactionTests {
    @Autowired
    private DemoService demoService;

    @Test
    public void testSave1(){
        System.out.println(demoService.save1());
    }
}

报错
在这里插入图片描述
没有插进去,说明数据回滚了
在这里插入图片描述

2.2 编程式事务

@Autowired
    private TransactionTemplate transactionTemplate;
    public Object save2(){
        //设置隔离级别
        transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        //设置传播机制
        transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

        //执行SQL访问事务
        return transactionTemplate.execute(new TransactionCallback<Object>() {
            @Override
            public Object doInTransaction(TransactionStatus transactionStatus) {
                //新增用户
                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/999.png");
                user.setCreateTime(new Date());

                userMapper.insertUser(user);

                //新增帖子
                DiscussPost post = new DiscussPost();
                post.setUserId(user.getId());
                post.setTitle("nihao");
                post.setContent("11");
                post.setCreateTime(new Date());
                discussPostMapper.insertDiscussPost(post);

                Integer.valueOf("abc");

                return "ok";
            }
        });

    }
    @Test
    public void testSave2(){
        System.out.println(demoService.save2());
    }

在这里插入图片描述
在这里插入图片描述

总结:两种管理事务的方式,平时优先选第一种,简单;如果要处理的业务比较复杂,只有中间一小部分的事务想管理,就用第二种

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-12-01 17:46:35  更:2021-12-01 17:47:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:31:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码