经常听人说事务,事务具有ACID,现在来说一说事务:
隔离性
事务的隔离,实际上是一个虚拟视图的创建。
隔离级别 | 意义 | 视图创建时间 |
---|---|---|
读未提交 | 一个事务还没提交时,他的变更就可以被别的事务看到 | 无 |
读提交 | 一个事务提交之后,他的变更才被其他事务看到 | 每个SQL开始执行时创建视图 |
可重复读 | 一个事务执行中看到的数据,和事务启动时看到的一致。其未提交的变更,其他事务也不可见 | 事务启动时创建视图 |
序列化 | 对于同一行记录,按顺序执行 | 加锁,没有视图 读加读锁 写加写锁 |
关于隔离级别的查询:
show VARIABLES LIKE 'transaction_isolation';
MySQL默认的隔离级别是可重复读
。其MVCC(多版本并发控制)就是依赖于事务的视图。
在每一个事务中存在着虚拟视图、修改的新记录、回滚到旧记录的记录(回滚段)。
尽量不要使用长事务,原因有下:
- 占空间。长事务会意味着系统里存在着很老的视图。再提交之前,这些东西会一直占用存储空间(期间会使用到磁盘和内存,参见第一节中的redo log部分)。
- 占有锁。锁资源占有时间长了会拖垮数据库的。
查询长事务,如下是查询事务时间超过60s的:
select * from information_schema.innodb_trx where TIME_TO_SEC(timediff(now(),trx_started))>60;
关闭长事务(MySQL默认为关闭的):
set AUTOCOMMIT =1;
幻读
在同一事物中,前后两次查询同一范围时,后一次查询看到了前一次查看没有看到的值。
幻读只发生在“当前读”下,且幻读仅指新插入的行。
select * from t where name='x' for update;
这就是一条当前读语句。