数据库的事务隔离与锁机制有什么差别和联系?www.zhihu.com
MySQL默认采用自动提交(AUTOCOMMIT)模式。也就是说,如果不是显式地开始一个事务,则每个查询都被当作一个事务执行提交操作。在当前连接中,可以通过设置AUTOCOMMIT变量来启用或者禁用自动提交模式;
1或者ON表示启用,0或者OFF表示禁用。当AUTOCOMMIT=0时,所有的查询都是在一个事务中,直到显式的执行COMMIT提交或者ROLLBACK回滚,该事务结束,同时又开始了另一个新事务。修改AUTOCOMMIT对非事务型的表,比如MyISAM或者内存表,不会有任何影响。对这类表来说,没有COMMIT或者ROLLBACK的概念,也也可以说是相当于一直处于AUTOCOMMIT启用的模式。
另外还有一些命令,在执行之前会强制执行COMMIT提交当前的活动事务。典型的例子,在数据定义语言(DDL)中,如果会导致大量数据改变的操作,比如ALTER TABLE,就是如此。
另外还有LOCK TABLES等其他语句也会导致同样的结果。
MYSQL可以通过SET TRANSACTION ISOLATION LEVEL 命令来设置隔离级别。新的隔离级别会在下一个事务开始的时候生效。可以在配置文件中设置整个数据库的隔离级别,也可以只改变当前会话的隔离级别;
MySQL能够识别所有的4个ANSI隔离级别,InnoDB引擎也支持所有的隔离级别。
在事务中混合使用存储引擎
在输入改变当前会话的隔离级别为
read committed之后
查询当前会话的事务隔离级别和全局隔离级别发现,只有当前事务的隔离级别发生了改变,全局隔离级别仍旧是可重复读。
好,那现在我们来实例验证下锁与隔离级别的关系;
1.读未提交
client1
client2
关闭自动提交事务
client1
client2
client1和2同时开始两个事务
同时进行查询,没有问题,读不加锁;
此时仍旧不结束事务,client1更新id为1的行的num值为-1
然后client2去查询,
可以在client1未提交事务的时候查到修改后的值,体现了读未提交;
然后client2也修改该行的值
由于client1未释放该行锁,所以client2修改失败
最终超时失败;
然后再次输入改指令并等待,同时client1输入提交事务指令;
这时client2的update立即成功了;
结果:在读未提交的隔离级别下,两个事务同时读没有,且一个事务可以看到另一个事务没有提交的修改,若两个事务同时修改一行中的某个值,先发生的可以执行,后发生的只能等另一个事务提交事务后释放锁后才能获取锁并修改该值;
读提交;
set session transaction isolation level read committed;
两个客户端都执行该指令;
当前
两个client同时读也没有问题;
client1修改
client2读取
可以读取,但是读取到的是旧值,这也是MVCC多版本控制的结果;
同样client2无法再client1未提交事务的情况下修改该行的值;
直到超时,不过可以修改另一行值
同样,client1这时也将无法修改id=2的行,如果尝试修改就将触发死锁;
结果:读提交,可以同时读,且一个事务不会读取到另一个事务未提交的内容;