什么是事务?
事务是指包含多个微小逻辑单元的一组操作, 只要其中有一个逻辑失败了,那么这一组操作就全部以失败告终,不存在一半成功,一半不成功的状况。
事务的特性
原子性(Atomicity) : 事务中的逻辑要全部执行,不可分割。(原子是物理中最小单位)
一致性(Consistency): 指事务执行前和执行后, 数据的完整性保持一致
隔离性(Isolation): 指一个事务在执行的过程中不应该受其他事务的影响
持久性(Durability): 事务执行结束(提交或回滚), 数据都应持久化到数据中
安全问题
读问题
脏读: 指 一个事务 读到了另一个事务还未提交的数据
不可重复读: 一个事务读到了另一个事务提交的数据, 导致多次查询结果不一致。
幻读: 一个事务读到了另一个事务已提交的插入的数据,导致多次查询结果不一致。
写问题
丢失更新:指一个事务去修改数据库, 另一个事务也修改数据库,最后的那个事务,不管是提交还是回滚都会造成前面一个事务的数据更新丢失
解决丢失更新,通常有两种方法: 悲观锁 和 乐观锁
悲观锁
指事务在一开始就认为丢失更新一定会发生, 这是一件很悲观的事情。 具体操作步骤如下:
1. 所有事务在执行操作前,先查询一次数据, 查询语句如下:
select * from student for update ; 后面的for update 其实是数据库锁机制 、 一种排他锁。
2. 哪个事务先执行这个语句, 哪个事务就持有了这把锁, 可以查询出来数据, 后面的事务再执行这条语句,不会有任何数据显示,就只能等着。
3. 一直等到前面的那个事务提交数据后, 后面的事务数据才会出来,那么才可以往下接着操作。
乐观锁
乐观锁是指,从来不会觉得丢失更新会发生。那么它的具体做法是什么呢?
要求程序员在数据库中添加字段,然后在后续更新的时候,对该字段进行判定比对, 如果一致才允许更新。
隔离级别
读未提交:
一个事务可以读取到另一个事务还未提交的数据。 这就会引发 “脏读” 读取到的是数据库内存中的数据,而并非真正磁盘上的数据。
读已提交:
与前面的读未提交刚好相反,这个隔离级别是 ,只能读取到其他事务已经提交的数据,那些没有提交的数据是读不出来的。但是这会造成一个问题是: 前后读取到的结果不一样。 发生了不可重复!!!, 所谓的不可重复读,就是不能执行多次读取,否则出现结果不一 。
不可重复读:
该隔离级别, 可以让事务在自己的会话中重复读取数据,并且不会出现结果不一样的状况,即使其他事务已经提交了,也依然还是显示以前的数据。
可串行化:
可以防止上面的所有问题,但是都使用该隔离级别也会有些问题。 比如造成并发的性能问题。 其他的事务必须得等当前正在操作表的事务先提交,才能接着往下,否则只能一直在等着。