首页 > 其他分享 >事务管理(十二)

事务管理(十二)

时间:2022-08-21 22:26:27浏览次数:60  
标签:事务管理 事务 10 Read 十二 user new post

1.概要

  • 什么是事务
    • 事务是由N步数据库操作序列组成的逻辑执行单元,这系列操作要么全执行,要么全放弃执行。
  • 事务的特性(ACID)
    • 原子性(Atomicity):事务是应用中不可再分的最小执行体。
    • 一致性(Consistency):事务执行的结果,须使数据从一个一致性状态,变为另一个一致性状态。
    • 隔离性(lsolation):各个事务的执行互不干扰,任何事务的内部操作对其他的事务都是隔离的。
    • 持久性(Durability):事务一旦提交,对数据所做的任何改变都要记录到永久存储器中。

2.事务的隔离性

  • 常见的并发异常
    • 第一类丢失更新、第二类丢失更新。
    • 脏读、不可重复读、幻读。
  • 常见的隔离级别
    • Read Uncommitted:读取未提交的数据。
    • Read Committed:读取已提交的数据。
    • Repeatable Read:可重复读。
    • Serializable:串行化。

3.第一类更新丢失

某一个事务的回滚,导致另外一个事务已更新的数据丢失了。

时刻 事务1 事务2
T1 Read: N = 10
T2 Read: N = 10
T3 Write: N = 9
T4 Commit: N = 9
T5 Write: N = 11
T6 Rollback: N = 10

4.第二类更新丢失

某一个事务的提交,导致另外一个事务已更新的数据丢失了。

时刻 事务1 事务2
T1 Read: N = 10
T2 Read: N = 10
T3 Write: N = 9
T4 Commit: N = 9
T5 Write: N = 11
T6 Commit: N = 10

5.脏读

某一个事务,读取了另外一个事务未提交的数据。

时刻 事务1 事务2
T1 Read: N = 10
T2 Write: N = 11
T3 Read: N = 11
T4 Rollback: N = 10

6.不可重复读

某一个事务,对同一个数据前后读取的结果不一致。

时刻 事务1 事务2
T1 Read: N = 10
T2 Read: N = 10
T3 Write: N = 11
T4 Commit: N = 11
T5 Read: N = 11

7.幻读

某一个事务,对同一个表前后查询到的行数不一致。

时刻 事务1 事务2
T1 Select: id < 10 (1,2,3)
T2 lnsert: id = 4
T3 Commit: id =(1,2,3,4)
T4 Select: id < 10 (1,2,3,4)

8.事务隔离级别

隔离级别 第一类丢失更新 脏读 第二类丢失更新 不可重复读 幻读
Read Uncommitted Y Y Y Y Y
Read Committed N N Y Y Y
Repeatable Read N N N N Y
Serializable N N N N N

9.实现机制

  • 悲观锁(数据库)
    • 共享锁(S锁)
      事务A对某数据加了共享锁后,其他事务只能对该数据加共享锁,但不能加排他锁。
    • 排他锁(X锁)
      事务A对某数据加了排他锁后,其他事务对该数据既不能加共享锁,也不能加排他锁。
  • 乐观锁(自定义)
    • 版本号、时间戳等
      在更新数据前,检查版本号是否发生变化。若变化则取消本次更新,否则就更新数据(版本号+1)。

10.Spring事务管理

  • 声明式事务
    • 通过XML配置,声明某方法的事务特征。
    • 通过注解,声明某方法的事务特征。
  • 编程式事务
    • 通过TransactionTemplate管理事务,并通过它执行数据库的操作。
    //声明式,用于整个方法
    @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("[email protected]");
        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";
    }

    // 编程式,可用于方法中的部分步骤
    public Object save2() {
        // TransactionTemplate 可由Spring容器注入
        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("[email protected]");
                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";
            }
        });
    }

标签:事务管理,事务,10,Read,十二,user,new,post
From: https://www.cnblogs.com/dalelee/p/16610967.html

相关文章

  • 【Spring5学习笔记(4)】事务管理:
    事务1、什么是事务(1)事务是数据库操作的最基本单元,是逻辑上的一组操作,要么都成功,如果有一个失败则所有操作都失败(2)经典场景:银行转账2、事务的四个特性(ACID)(1)原子性:一组逻辑操......
  • 【kuangbin】专题十二 基础DP1
    【kuangbin】专题十二基础DP1https://vjudge.net/contest/68966#overview前几周写了来着,忘更了我饿了,先放代码,吃完再来A-MaxSumPlusPlus#include<bits/stdc++.......
  • SpringBoot 之 事务管理
    我们在开发企业应用时,由于数据操作在顺序执行的过程中,线上可能有各种无法预知的问题,任何一步操作都有可能发生异常,异常则会导致后续的操作无法完成。此时由于业务逻辑......
  • linux-0.11分析:进程初始化函数init(),第二部分(void) open("/dev/tty0",O_RDWR,0),第十
    第二部分,(void)open("/dev/tty0",O_RDWR,0);参考[github这个博主的厉害][https://github.com/sunym1993/flash-linux0.11-talk]它会触发一个int0x80中断,会找的sys_......
  • 20220816 第一组 于芮 数据库查询(第三十二天)
     小白成长记——第三十二天   今天是学数据库的第二天,学习的内容比昨天要稍微难一点,但是还是很好理解的,知识量很大,需要记忆的很多,很考验脑容量,但是还是要认真学习......
  • 前端周刊第三十二期
    前端周刊发表每周前端技术相关的大事件、文章教程、一些框架的版本更新、以及代码和工具。每周定期发表,欢迎大家关注、转载。如果外链不能访问,关注公众号「前端每周看」,里......
  • 自定义组件⑤纯数据字段-微信小程序开发(二十二)
    1.什么是纯数据字段概念:纯数据字段指的是那些不用于界面渲染的data字段。应用场景:例如有些情况下,某些data中的字段既不会展示在界面上,也不会传递给其他组件,仅仅在当......