- 数据库事务
- 原子性:组成一个事务的多个数据库操作为一个整体,只有全部成功才能提交,只要一个失败就需要全部回滚撤销。
- 一致性:事务成功后,数据库状态和他的业务规则要一致。
- 隔离性:不同事物之间不会互相干扰。但实际中并不会要求完全不会干扰,不同的事务隔离级别对于不同的干扰程度。
- 持久性:一旦事务成功,所有数据都需要被持久化到数据库中。
- 数据并发的问题
- 脏读:A事务读到了B事务未提交更改的数据,并在这个数据的基础上进行操作。如果B事务回滚,A事务的操作就是有问题的。
- 不可重复读:A读取了B事务已提交的数据修改。也就是在同一事物中,多次读取同一数据发生了不一致。
- 幻读:A事务读取了B事务提交的新增数据,这是会出现幻读。幻读和不可重复读比较类似,区别在于新增和更新。幻读需要添加表级锁才能解决,而不可重复读添加行锁即可。
- 第一类数据更新丢失:A事务撤销时,把B事务提交更新的数据覆盖了。
- 第二类数据更新丢失:A事务提交后,把B事务提交更新的数据覆盖了。
- 数据库的锁机制(MySQL)
- 共享/排他锁:
- 共享锁 S:读取数据使用,读读可并行
- 排它锁 X:修改数据使用:写读,写写不可并行
- 意向锁:
- 表级锁:InnoDB为支持多粒度锁机制,允许表级锁和行级锁共存。意向锁代表,未来的某个时刻,事务可能要加共享或排它锁,先提前声明一个意向。意向锁只代表意向,所以意向锁之间可以兼容。也就是不同事物可以同时给同一张表添加意向锁。
- 意向共享锁 IS:事务可能要添加共享锁,只有先获得表的IS锁,才能获得对应的S锁
- 意向排它锁 IX:事务可能要添加排它锁,只有先获得表的IX锁,才能获得对应的X锁。一旦某个事务添加了意向排它锁或排它锁,那么其他事务不能添加普通的排它锁和共享锁了。
- 记录锁:封锁锁索引记录,这里锁的是索引
- 锁的是非主键索引,会在索引记录加锁然后再去主键索引加锁
- 表上如果没有索引,会隐式的在主键索引加锁
- 如果要锁的列没有索引,会在全表记录加锁
- 间隙锁,封锁索引记录中的间隔,防止其他事物插入某个索引记录区间,并且防止更新数据到区间内。主要用于防止不可重复读,事务隔离级别降为为RC后,间隙锁自动失效。
- 临键锁:是记录锁和间隙锁的组合,既锁索引也锁索引记录。当索引含有唯一属性,自动降级为记录锁,只锁本身不锁范围。
- 插入意向锁:间隙锁的一种,专门针对insert操作。同索引,同范围,不同事务插入的位置不冲突,不会阻塞。
- 自增锁:专门针对自增字段,保证插入字段都是连续自增的。表级锁。
- 共享/排他锁:
- 事务隔离级别
- 读未提交:最低级别,会造成脏读,不可重复读,幻读
- 读已提交:RC级别会对读取到的记录加记录锁,保证只能读取到已提交事务的数据,不会出现脏读,会出现不可重复读,幻读。
- 重复读:可以解决不可重复读,但仍存在幻读问题。MYSQL用MVCC解决读写并发问题,间隙锁解决写写并发问题,从而处理幻读问题。
- 串行化:效率低下,但解决了所有问题。
- 七种事务传播行为
- REQUIRED:没有则创建,有则加入
- SUPPORTS:没有就没有,有则加入
- MANDATORY:没有则抛异常,有则加入
- REQUIRED_NEW:必须用新的,旧事务挂起
- NOT_SUPPORTED:不使用事务,有则挂起
- NEVER:有则抛异常,没有就以非事务运行
- NESTED:有则嵌套事务内执行,没有则新建一个事务
事务的一些小知识
最新推荐文章于 2024-07-05 19:33:44 发布