03-事务

定义

保证一组操作要么全部成功,要么全部失败。
引擎层实现

ACID特性

ACID(Atomicity、Consistency、Isolation、Durability,即原子性、一致性、隔离性、持久性)

  • 原子性:最小操作单位
  • 一致性:事务操作前后,数据总量不变
  • 隔离性:多个事务间,相互独立
  • 持久性:提交、回滚后,持久化保存

隔离性 & 隔离级别

  • 读未提交(read uncommitted):
    读到了其他事务未提交的数据,即脏读(dirty read)
  • 读已提交(read committed):
    其他事务提交前、提交后,当前事务两次查询到的数据不一致,即不可重复读(non-repeatable read)
  • 可重复读(repeatable read):
    保证一个事务执行过程中看到数据前后一致。但假如其他事务有insert、delete、update操作,改变了数据量,当前事务将无法通过select获得这些改变结果,即幻读(phantom read)。
    另外的解释:某一次的 select 操作得到的结果所表征的数据状态无法支撑后续的业务操作。
  • 串行化(serializable)
    将记录加锁,锁冲突时必须等待当前操作事务的提交或回滚后,才能操作。
    解决一切问题

修改隔离界别:

-- 可选参数有:
-- READ-UNCOMMITTED, 
-- READ-COMMITTED, 
-- REPEATABLE-READ,
-- SERIALIZABLE
transaction-isolation = xxx

事务隔离的实现

各个read-view通过回滚日志,读取到一个数值的不同版本,这是通过MVCC多版本并发控制实现的。
一个回滚日志,将在系统里没有比此日志更早的read-view的时候被删除。


建议:尽量避免使用长事务。

  • 占用大量存储空间:
    长事务中存在许多老旧的任务视图,这个长事务提交前,它可能用到的回滚记录都必须保留,导致占用大量存储空间。
  • 占用锁资源
-- 查询持续时间超过60s的长事务
select * from information_schema.innodb_trx 
where TIME_TO_SEC(timediff(now(),trx_started))>60
回滚日志

事务启动方式

-- 1、显示启动事务-----------------------------
begin transaction
## 或
start transaction
# 具体操作
commit
## 或
rollback
-- 2、关闭当前线程自动提交--------------------
set autocommit=0
# 具体操作
# 任何query语句都将启动事务,且必须手动提交或回滚
# 可能导致意外的长事务
commit
## 或
rollback

建议:使用显示启动事务的方式

如何避免长事务对业务的影响

应用开发端:

  • 打开自动提交:set autocommit=1
  • 确认是否有不必要的只读业务,可以去掉。
  • set max_execution_time,控制每个语句的最长执行时间。

数据库端:

  • 监控information_schema.innodb_trx表,设置长事务阈值,超过就报警、KILL
  • 业务功能测试阶段,输出所有general_log,分析日志行为,提前发现
  • 5.6 or higher,把innodb_undo_tablespaces设置成2
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容