一、什么是事务
事务(Transaction)是数据库操作的一个逻辑单元,它包含了一系列的操作。这些操作要么全部成功(提交,commit),要么全部失败(回滚,rollback),以保证数据的一致性和完整性。例如,银行转账系统中,从一个账户扣除金额和向另一个账户增加金额这两个操作必须作为一个整体来执行,如果其中一个操作失败,那么整个转账过程应该回滚,两个账户的余额都不应该发生变化。
二、事物的四大特性ACID
-
原子性(Atomicity):事务中的所有操作要么全部完成,要么全部不完成。事务在执行过程中发生错误,会被回滚到事务开始前的状态,就像这个事务从来没有执行过一样。
-
一致性(Consistency):事务执行前后,数据库必须从一种一致性状态变换到另一种一致性状态。换句话说,事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。
-
隔离性(Isolation):一个事务的执行不能被其他事务干扰。并发执行的事务之间不能互相影响。
-
持久性(Durability):事务一旦提交,它对数据库中数据的改变就是永久性的,即使系统崩溃也不会丢失。
三、并发事务引发的问题
以MYSQL为例,MySQL 服务端是允许多个客户端连接的,这意味着 MySQL 会出现同时处理多个事务的情况。那么在同时处理多个事务的时候,就可能出现脏读(dirty read)、不可重复读(non-repeatable read)、幻读(phantom read)的问题。
脏读
脏读就是在一个事务处理过程中读取了另一个未提交的事务的数据
例:假如A、B各有100元钱,A向B转了100元钱
执行
update account set money=money+100 where name=‘b’;
update account set money=money-100 where name=‘a’;
当执行完第一条语句时,第二条还没执行,B查询自己的账户,就会发现自己的账户多了100元,变为200元,如果此时A回滚自己的操作,那么B之后再查询自己的账户,就会发现自己的账户还是100元。
例:张三的原工资为1000元,财务人员将张三的工资改为8000元,但是未提交事务
张三读取自己的工资,发现是8000元
财务发现操作有误,回滚了事务,张三的工资又变为1000
那么张三读取的工资8000就是一个脏数据
不可重复读
不可重复读是指在一个事务内,多次读同一数据,在这个事务没有结束之前,另外一个事物也读取该数据,那么在第一个事物中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的数据可能就是不一样的。
不可重复读的重点在于修改:同样的条件,读过的数据,再次读取出来的值不一样了。
例:转账之前,银行查询A的账户是100元,A向B转了100之后,银行对应上面两个sql语句并且已经提交ÿ