目录
DML则会受autocommit的影响,分为隐性开始和显性开始,而DDL和DCL不会受影响。
SELECT....LOCK IN SHARE MODE 共享锁语句:
一、什么是事务?
一件事情完成了一个任务,里面包含了很多的操作 --》事务
一个数据库事务由一条或者多条SQL语句构成,它们形成一个逻辑的工作单元,这些SQL语句要么全部执行成功,要么全部执行失败
我们的存储引擎Innodb就可以使用事务这个功能。
二、事务的开始和结束:
在mysql中,系统变量@@autocommit默认是打开的,这意味着任何一条SQL语句都会开始一个事务,语句执行完成后事务自动结束。
在实际使用中,应该使用SET语句来关闭自动提交,否则一个事务不可能由多条SQL语句构成。
我们可以使用如下方法关闭autocommit。autocommit--》自动commit(提交)数据到disk磁盘。
但是我们建表或者修改权限,并不会收autocommit影响。(DDL和DCL不受autocommit的影响,他们会自动的执行commit,自动的去提交)(我们使用autocommit=1表示打开了自动提交功能)
DML则会受autocommit的影响,分为隐性开始和显性开始,而DDL和DCL不会受影响。
例如:
START TRANSACTION 表示开启一个事务!
SAVEPOINT 表示保存点命令,用来做一个标记,专门给ROLLBACK TO命令使用(前提是我们的autocommit已经关闭了等于0 )
而我们使用ROLLBACK TO表示回滚操作,专门用来撤销事务 所做的部分工作(其中ROLLBACK TO b 表示回滚 delete from trans_demo where id=2;的操作)。
如果我们直接ROLLBACK,那么他就会直接回滚整个事务里的所有操作,但是不包括创建trans_demo表的操作,因为它是DDL操作。
因此我们想要一个事件结束,必须要commit一下(数据保存到disk磁盘中)。
COMMIT是提交事件给磁盘,而ROLLBACK是回滚事件内的操作!
COMMIT或者BOLLBACK语句之前的数据状态:
因此可以看出,我们使用start transaction去操作表的时候,对会话添加的是表锁。
并发事务的4个问题:(脏读、不可重复读、幻读、丢失更新)
解决并发问题的4个隔离级别:
我们可以通过下图所示查看Mysql内的隔离级别(隔离级别越高,性能可能会更低一点)
事务的4个属性:(原子性、一致性、隔离性、持久性)
事务机制可以确保数据一致性。
事务应该具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性。
- 原子性(atomicity)。一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。
- 一致性(consistency)。事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
- 隔离性(isolation)。一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
- 持久性(durability)。持续性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
三、锁(表锁、行锁、读锁、写锁、共享锁、排他锁):
颗粒度:
1、表锁 Innodb也支持(因为它支持行锁,而行锁的颗粒度更小一点)
2、行锁 Innodb支持
行为:
1、读锁 备份的时候、当前会话和其他会话都可以读表,但是不能修改表
2、写锁 当前会话可以读写表,但是其他的会话既不能读也不能写。
3、共享锁
4、排他锁
什么是死锁,什么是活锁,他们的区别是什么?
死锁是指两个或多个进程无限期地等待对方释放资源而无法继续执行的情况。简单来说,就是多个进程互相等待对方释放资源,导致所有进程都无法继续执行,形成了一种僵局状态。死锁是操作系统中的一种常见问题,如果不加以处理,会导致系统性能下降甚至崩溃。
活锁是一种并发问题,指两个或多个线程在互相等待对方完成某一操作,导致它们都不能继续执行的情况。与死锁不同,活锁中的线程不会被阻塞,它们会不断重试操作,但仍然无法进展。活锁通常发生在多个线程试图以相同的方式争夺资源时,例如两个人在狭窄的门口相互让步,但却总是同时向同一方向让步,导致无法通过。
死锁是指两个或多个线程互相持有对方需要的资源,导致它们都无法继续执行,陷入了无限等待的状态。这种情况下,线程被永久阻塞,程序无法继续执行下去。
活锁是指两个或多个线程在尝试解决死锁问题时,不断地改变自己的状态,但最终仍然无法解决问题,导致它们一直在忙碌而无法继续执行。这种情况下,线程并没有被阻塞,但它们却无法完成任务,程序也无法继续执行下去。
简而言之,死锁是线程被阻塞了,而活锁是线程处于忙碌但无法完成任务的状态。
还有悲观锁和乐观锁的概念。