四大特性:
四大特性 | 含义 |
---|---|
原子性 | 一个事务要么成功,要么失败 |
一致性 | 一个事务执行之前跟执行之后状态保持一致 |
例 | A和B一共100元,无论中间转账多少次、转多少,最终两人的钱加一起还是100元 |
隔离性 | 两个事务之间互不干扰 |
例 | A给B转账,不会影响到B给C转账,属于两个事务 |
持久性 | 事务一旦提交,永久保存 |
隔离级别
隔离级别 | 可能出现的情况 |
---|---|
读未提交(Read Uncommitted) | 最危险,什么情况都有可能发生:脏读、不可重复读、幻读 |
读已提交(Read Committed) | 防止脏读、但可能会出现不可重复读、幻读 |
可重复读(Repeatable Read) | 数据库默认 隔离级别,但也有可能出现幻读 |
串行化(Serializable) | 级别最高,相当与单线程,全表锁,一次只能执行一个事务,相应的执行效率最差 |
注意:
1.隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。
2.对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed
。
3.Read Committed,它能够避免脏读取,而且具有较好的并发性能。虽然它会导致不可重复读、幻读,但是可以用悲观锁和乐观锁解决。
1.查看数据库隔离级别?
show variables like "%isolation%”;
或
select @@tx_isolation;
事务隔离之前是如下结果:
Variable_name | Value |
---|---|
transaction_isolation | REPEATABLE-READ |
tx_isolation | REPEATABLE-READ |
2.把隔离级别修改为read committed
全局修改
set global transaction isolation level read committed;
本次事务修改
set session transaction isolation level read committed;
事务修改之后是如下结果:
Variable_name | Value |
---|---|
transaction_isolation | READ-COMMITTED |
tx_isolation | READ-COMMITTED |
悲观锁
悲观锁:跟表锁差不多,以订单为例:当用户a查询库存时,先上锁,如果不释放锁,可能一直造成阻塞,甚至会出现死锁的情况。
乐观锁
乐观锁:每个用户更改库存之前都会先查询一下,如果和之前查的库存一样,就更改库存,如果不一样就重新查询,看购买量是否小于库存,如果小于库存,也可以下单。
排它锁
对于UPDATE、DELETE、INSERT语句句,InnoDB会⾃自动给涉及数据集加排他锁(X)
读锁、写锁
MyISAM在执⾏查询语句SELECT前,会⾃自动给涉及的所有表加读锁,在执⾏更新操作(UPDATE、DELETE、INSERT等)前,会⾃动添加写锁,这个过程并不不需要用户⼲预,所以,只会在某些特定的场景下才需要⼿动加锁。
表锁
开销⼩,加锁快;不会出现死锁;锁定力度⼤,发⽣锁冲突概率高,并发度最低
行锁
开销大,加锁慢;会出现死锁;锁定粒度小,发⽣锁冲突的概率低,并发度⾼
InnoDB既支持行锁也支持表锁。 MyISAM只⽀支持表锁
InnoDB的行锁是基于索引的,只有通过索引条件检索数据才使⽤行级锁,否则,InnoDB将使用表锁。
读锁和写锁是互斥的,读写操作是串⾏。 如果某个进程想要获取读锁,同时另外⼀个进程想要获取写锁。在mysql⾥边,写锁是优先于读锁的!
写锁和读锁优先级的问题是可以通过参数调节的:max_write_lock_count和low_priority_updates
MyISAM可以⽀持查询和插入操作的并发进行。可以通过系统变量concurrent_insert来指定哪种模式,在MyISAM中它默认是:如果MyISAM有空洞(即表的中间没有被删除的行),MyISAM允许在一个进程读表的同时,另一个进程从表尾插⼊记录。 但是InnoDB存储引擎是不支持的!
参考:https://baike.baidu.com/item/%E6%95%B0%E6%8D%AE%E5%BA%93%E4%BA%8B%E5%8A%A1/9744607?fr=aladdin
https://baike.baidu.com/item/%E4%BA%8B%E5%8A%A1%E9%9A%94%E7%A6%BB%E7%BA%A7%E5%88%AB/2638091