事务未解之谜
1、什么是事务??------先晕会吧
事务是由一个或者一组Sql组成的单独单元。在单独单元内,要么全部的Sql执行成功,要么全部失败。(只要有一条Sql执行失败,则会进行回滚。)
2、事务的特性(ACID)
(1)A:Automicity(原子性)
原子性指的是事务中的操作,要么都做,要么都不做。(操作主要指的是事务中的一系列Sql操作)
(2)C:consistency(一致性)
一致性指的是语义上的一致性。而非语法上的一致性。就是使数据从一个一致性状态切换到另外一个一致性状态。----其实我觉得重点在于业务逻辑。
举例说明:转账(如A转账给B 100元)
在业务场景应该是:A= A-100 B=B-100
如果只保持原子性的话 在它的事务当中写上 :A=A-100 || A=A-100 ,B=B-100 || B=B-100 都是没错的
但如果要保持一致性的话 则应写上 A=A-100 ,B=B-100 ,这样才满足语义上的一致性。表达的就是A扣钱了,则B也必须要加钱。
(3)I:isolation(隔离性)
隔离性指的是并发事务之间互不干扰,互不影响。
(4)D:duration(持久性)
持久性指的是事务成功提交后,对数据库的改变的永久的。
3、并发事务带来的问题:
(1)脏读 (读到未提交的数据)
所谓脏读,就是在一个事务中读到了另外一个未提交事务的数据。
(2)不可重复读(读到已提交的数据,主要针对update操作)
所谓不可重复读,是指在一次事务中,针对同一条数据查询到了两次不一样的结果。
(3)幻读(读到已提交的数据,主要针对insert,delete操作)
所谓幻读就是在一次事务中,针对某部分数据查询到了两次不一样的结果。
(4)更新丢失
所谓更新丢失就是前一次事务提交的结果被后一次事务提交的结果给覆盖了。
4、事务的隔离级别:
(1)读未提交(READ_UNCOMMITTED) ------隔离级别最低
可以读取到未提交事务的数据
问题:可能出现脏读 。。。。。
(2)读已提交(READ_COMMITTED)
只能读取已提交事务的数据。
问题:可解决脏读,但是不能解决不可重复读和幻读。
(3)可重复读(REPEATABLE_READ)
多次读取同一条数据时,数据的值和事务最开始的值是一样的。
问题:可解决脏读,不可重复读,但不能解决幻读。
(4)串行化(SERIALIZABLE)
所有事务按顺序执行,只能一个一个处理。
问题:可以解决脏读,幻读,不可重复读,但是效率低。
5、常见数据库的隔离级别
(1)Mysql
REPEATABLE_READ 可重复读
(2) oracle
READ_COMMITTED 读已提交
(3)sql server
READ_COMMITTED 读已提交