事务:
-
原子性 : 要么都执行,要么都不执行。
-
一致性: 多个事务并行执行的结果和多个事务串行执行的结果是一致的。
-
隔离性: 事务之间是互不干扰的
-
持久性: 事务一旦被提交,对数据库的改变是永久性的。
事务的隔离级别:
-
未提交读: 脏读
-
一个事务读取了别的事务修改了但未提交的数据
-
-
提交读:不可重复读
-
同一个事务读取到的数据不同 ,可能是被别的事务把数据修改了
-
-
可重复读:幻读 (mysql默认的事务隔离级别)
-
分配一个版本号 ,只读这一个版本号 ,解决了提交读的问题 但可能读取到的数据跟库里面不一致
-
-
可串行读
-
事务的最高隔离级别,强制事务排序 ,加共享锁
-
可以解决脏读、不可重复读、幻读问题,但会导致大量的超时和锁竞争关系,一般不推荐使用
-
mysql中的锁
MyISAM和InnoDB支持的锁类型**(mysql的两种最常用数据库引擎)
乐观锁悲观锁作用
-
在并发访问情况下,很有可能出现不可重复读等等读现象。
-
为了更好的应对高并发,封锁、时间戳、乐观并发控制(乐观锁)、 悲观并发控制(悲观锁)都是并发控制采用的主要技术方式。
悲观锁(读取数据就加锁)
-
总是假设最坏的情况,每次去读数据的时候都认为别人会修改,所以每次读取数据的时候就加上一把锁
在读取之前就加锁,期间其他用户阻塞等待访问该记录。
乐观锁(读取数据不加锁,修改数据加锁)
-
总是假设最好的情况,每次去读数据的时候认为别人不会修改,所以每次读取数据的时候不用加锁
在更新数据在加一把锁
-
在更新数据的时候需要比较程序中的库存量与数据库中的库存量是否相等,如果相等则进行更新
反之程序重新获取库存量,再次进行比较,直到两个库存量的数值相等才进行数据更新。
使用场景
-
乐观锁适用于写比较少的情况下(多读场景),即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。
-
悲观锁适用于读比较少的情况下(多写场景),如果是多写的情况,一般会经常产生冲突,这就会导致上层应用会不断的进行retry,这样反倒是降低了性能,所以一般多写的场景下用悲观锁就比较合适。
共享锁
-
共享锁又叫读锁,如果事务T对A加上共享锁,则其它事务只能对A再加共享锁,不能加其它锁。
-
获准共享锁的事务只能读数据,不能写数据。
排它锁
-
排它锁又叫写锁,如果事务T对A加上排它锁,则其它事务都不能对A加任何类型的锁。获准排它锁的事务既能读数据,又能写数据。