05 August 2018

事务的特性

原子性:事务里面的多个操作,要么都完成,要么都失败。
持久性:对数据的修改是持久的。
隔离性
一致性

隔离性怎么理解

隔离性要根据数据库的隔离级别来讨论,隔离到什么程度。
最高级别就是所有的事务都互不影响,没有并行化,都是串行化执行。
最低级别就是不隔离,事务执行过程中,假如并行了,数据改来改去对其他事务都是可见的。

mysql> show variables like 'tx_isolation';
- RU (read uncommitted)
- RC (read committed)
- RR (repeatable read)
- serializable


RU 是不被建议的(存在脏读),serializable 效率太差。
RC 和 RR 的区别:
RC 可以读到其他事务已经 commit 到的数据。这会造成两次 select 的结果不同。
RR 可以保证在这次事务内,其他事务 commit 的数据不会影响到当前的版本。

一致性怎么理解

如何理解数据库事务中的一致性的概念? - 知乎
https://www.zhihu.com/question/31346392

如何理解数据库事务中的一致性的概念? - 斯图亚特的回答 - 知乎
https://www.zhihu.com/question/31346392/answer/156510491
一致性就是如果你做个银行数据库的话,无论怎么转账,钱的总数都不变。

如何理解数据库事务中的一致性的概念? - 孟波的回答 - 知乎
https://www.zhihu.com/question/31346392/answer/362597203
这个词在不同的环境下有着不同的含义,被极大的滥用了,导致很难理解:
1. 多副本的一致性
2. 一致性 hash.
3. CAP 理论的一致性
4. ACID 里的一致性
而这几个一致性的含义都
不是一回事!
不是一回事!
不是一回事!

事务的持久性

innodb 的持久性由两个配置决定

innodb_flush_log_at_trx_commit=1  多少次提交事务之后就开始写入到 binlog 里面
sync_binlog=1                     多少次写到 binlog 之后多久开始刷新到磁盘(调用 fdatasync)

什么时候会获得 “读锁”

select 语句加了 lock in share mode (select * from tb where id = 1 lock in share mode)

什么时候会获得 “写锁”

  1. 写数据库的时候 (例如 update)
  2. 读数据 (select * from xxx where xxx for update)

锁的使用

没有用到锁
mysql> start transaction;
mysql> select * from tb where id = 1;
mysql> xxx;
mysql> commit;

id = 1 的读锁
mysql> start transaction;
mysql> select * from tb where id = 1 lock in share mode;
mysql> xxx;
mysql> commit;

id = 1 的写锁
mysql> start transaction;
mysql> select * from tb where id = 1 for update;
mysql> xxx;
mysql> commit;

id = 1 的写锁
mysql> start transaction;
mysql> update tb set name="xxx" where id = 1;
mysql> xxx;
mysql> commit;

加了读锁,其他事务只能读,不能 update
加了写锁,其他事务连读都不能读 (即会被阻塞,直到事务被 commit)

写锁的范围

innodb 的锁是作用在索引上的。一个事务,如果没有根据索引去更新数据,那么 innodb 会锁住整个表

mysql> update tb set age = xxx where name = "xxx";

如果 name 有索引,那么只会锁住对应的行;
如果 name 没有索引,那么其他事务的更新语句都会被 block 住