事务隔离:为什么你改了我还看不见

MyISAM引擎不支持事务。

隔离型与隔离级别

事务分为:A(Atomicity,原子性)C(Consistency,一致性)I(Isolation,隔离性)D(Durability,持久性)。

当数据库上多个事务同时执行的时候,就可能痴线脏读、不可重复读、幻读的问题,为了解决这些问题,需要使用到隔离级别的概念。

SQL标准的事务隔离级别包括:读未提交(read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(serializable)。

  • 读未提交:一个事务还没提交时,它做的变更就能被别的事务看到。
  • 读提交:一个事务提交之后,它做的变更才能被其他事务看到。
  • 可重复读:一个事务执行过程中看到的数据,总是跟这个事务在启动是看到的数据是一致的。当然在可重复读隔离级别下,为提交事务变更对其他事务是不可见的。
  • 串行化:对于同一行记录,写会加写锁,读会加读锁。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。

在实际情况中,数据库里面会创建一个视图,访问的时候以视图的逻辑结果为准。在可重复读隔离级别下,
这个事务是在事务启动的时候创建,整个事务存在期间都用这个视图;在读提交隔离级别下,这个视图是在每个sql语句开始执行的时候创建的;
读未提交隔离级别下直接返回记录最新值,没有视图概念;串行化隔离级别下直接用加锁的方式来避免并行访问。

Oracle数据默认隔离级别是读提交。

事务隔离的实现

在MySQL中,实际上每条记录在更新的时候都会同时记录一条回滚操作。记录上的最新值,通过回滚操作,都可以得到前一个状态的值。
不同时刻启动的事务会有不同的read-view,同一条记录在系统中可以存在多个版本,这就是数据库的多版本并发控制。
在没有事务再需要用到这些回滚日志时,回滚日志会被删除。当系统里没有比这个回滚日志更早的read-view的时候。

为什么不建议使用长事务?

长事务意味着存在很老的事务视图。由于这些事务随时可能访问数据库里面的任何数据,所以这个事务提交之前,数据库里面它可能用到的回滚记录都必须保留,
这样会导致大量占用存储空间。并且长事务还占用锁资源,也可能会拖垮整个库。

事务的启动方式

MySQL的事务启动方式如下:

  • 显示启动事务语句,begin 或 start transaction.配套的提交语句是commit,回滚语句是rollback。
  • set autocommit=0.线程的自动提交关闭。这个事务持续存在知道你主动提交commit或者rollback语句,或者断开链接。

有些客户端默认关闭自动提交,需要显示设置 set autocommit=1。

为了减少频繁提交事务的时间,可以使用commit work and chain,在提交事务并启动下一个事务。

你可能感兴趣的:(事务隔离:为什么你改了我还看不见)