事务浅析

Ⅰ、事务概述

  • 事务是一个程序的执行单元
  • 事务由一组sql组成(可以是1条或者多条)

tips:

一个事务可以有多条sql组成,tps是每秒的事务量,仅仅通过tps判断业务量高和低是不太准确的,如果事务里面sql比较多,即使tps比较低,那实际qps又是比较高的

Ⅱ、事务的特性

大家都知道事务的特性叫ACID,我们这把用很通俗的语言来描述这四个特性,具体实现后面再分析

  • A——atomicity(原子性)
    一个事务内所有sql操作是原子的,要么都做要么都不做

原子性由redo保证

  • C——consistency(一致性)
    事务前后状态保持一致,不破坏数据结构和约束

一致性由undo保证

  • I——isolation(隔离性)
    一个事务所做的修改对其他事务不可见,好似串行执行(和事务隔离级别是两个概念)

隔离性由lock保证

  • D——durable(持久性)
    一旦写了,数据不会丢失

持久性由redo和undo保证

Ⅲ、事务的类型

事务类型 说明
flat transactions 扁平事务,最常见的事务
flat transactions with savepoints 带保存点的事务
chained transactions 链事务,一个事务commit之后自动begin,没意义
nested transactions 嵌套事务,目前无数据库支持
distributed transactions 分布式环境下的扁平事务,每个节点支持acid,这是事务acid更高的标准
long transactions 运行时间非常长的事务,比如银行利息业务,这种事务会主从延迟,尽量拆成小事务(和online ddl用pt一样,不是为了加速,而是变慢达到降低主从延迟的目的)

tips:

  • 分布式事务案例:工行转账1w元到农行

    其实这个并不是用分布式事务做的,骗骗人的,所有银行网络打通?不存在的,后面详细讲这个问题

  • 主从延迟是mysql这几年面临的比较头疼的问题,主从复制的机制是用binlog来搞而不是像oracle那样用物理日志做

  • innodb除了嵌套事务其他都支持,myisam不支持事务

Ⅳ、事务操作

4.1 开启/关闭事务

法1:
begin;
xxx...;
commit/rollback;

法2:
start transaction;
xxx...;
commit/rollback;

为什么有第二种方法?
因为begin在存储过程中是一个关键字,嘿嘿...
  • 一个好习惯

    1、不管做什么,先打个begin,安全,不打begin就会auto commit自动提交,oracle不会自动提交

    2、show variables like 'autocommit'; 默认值是1 这个设成0,这样再直接delete就可以rollback

4.2 另一个玩法

begin;
aaa
savepoint s1;   设置一个保存点
bbb
rollback to s1;  回滚到aaa,aaa还没提交
这时候新开一个session,进去是看不到aaa的
最后还要commit或者rollback,当然也可以继续执行其他操作再去commit或者rollback

4.3 线上常见问题一例

线上业务经常会碰到代码里没有commit,导致事务对应的所有的锁占用的资源都没有释放,导致其他线程使用到对应资源都没办法提交

如何发现?

show processlist;满足如下4个条件:

1、用户是开发的账号
2、Command为sleep
3、Time非常大
4、Info为NULL

tips:

  • 线上sleep的线程很多没问题,但是这个time并不会很高

  • 通常我们用的都是线程池自动维护线程的活跃,每隔一段时间会维护一次(发个select 1来保持连通性,所以这个time应该和维护周期是一致的),发现不对劲我们可以手动kill掉这些进程

  • select * from information_schema.innodb_trxG也可以看,不过上面那种更方便

原文地址:https://www.cnblogs.com/---wunian/p/9062342.html