这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战
有关事务的几个问答,以此来更好的理解事务
什么是事务?
一组数据库的操作,要么全部成功,要么全部失败
为什么MyISAM会被InnoDB替代
因为事务是在引擎层实现的,MyISAM中没有事务,而InnoDB中有,这是MyISAM被InnoDB替代的一个原因 前一章中也说了,InnoDB中redo log有crash-safe的能力,redo log也是InnoDB特有的。防止数据库在异常重启时,记录丢失
隔离性是什么?
事务有四个特性 - A(Atomicity)C(consistency)I(isolation)D(Durability) 其中的I就是事务的隔离性
隔离级别是什么,有哪些?
隔离级别的作用就是 数据库中可能会有几个事务同时发生的情况。为了防止脏读(dirty read)、不可重复读(none-repeatable read)、幻读(phantom read),有读未提交、读提交、可重复读、串行化四类 读未提交的意思是事务未提交,其他事务已经能够读取到更新的数据 读提交 - 事务要提交之后,更新值才能被其他事务所读取 可重复读 - 事务在执行时的数据要和启动时的数据保持一致 串行化 - 事务读有"读锁",写有“写锁”。当读写锁发生冲突时,后一个事务只有等待前一个事务提交完毕后才会继续执行
四种隔离级别的异同?
数据库会创建视图,访问时以视图的逻辑结果为准
读未提交 - 直接返回记录上的最新值,没有视图的概念
读提交 - 每个SQL语句开始执行时会创建一个视图
可重复读 - 事务启动时会创建一个视图 - 整个事务存在期间都用这个视图
串行化 - 加锁的方式避免了并行访问
Oracle默认的隔离级别是读提交 - 因此当从Oracle迁移到MySQL的应用。要将MySQL的隔离级别设置成读提交 即 transaction_isolation 设置为 Read-committed
通过show-variables 查看当前的值
事务隔离的具体实现 - 以可重复读为例
每次记录 - 更新的时候 - 会记录一条回滚操作
同一条记录在系统中会有多个版本 - 数据库的多版本并发控制(MVCC)
回滚日志何时删除 系统中没有比这个回滚日志更早的read-view
为何尽量不要使用长事务
系统中存在的很老的事务视图
这些事务随时可能访问数据库里面的任何资源 因此,这些事务提交之前 - 数据库里面它可能用到的回滚记录都必须保留 导致占用大量存储空间
事务的启动方式是怎样的?
显示启动事务语句 - begin/start transaction
配套提交语句 - commit 回滚语句 - rollback
set autocommit = 0 将这个线程的自动提交关掉
这个事务持续存在直到主动执行commit或rollback语句或断开连接
建议 set autocommit = 1 - 通过显示语句的方式来启动事务
如果为频繁使用事务的业务减少交互次数
set autocommit = 0 每个事务在开始时都不需要主动执行一次"begin" - 减少了交互次数。但需要主动断开连接
执行commit work and chain 提交事务并自动启动下一个事务 省去了再次执行begin语法的开销。