数据库事务
事务是什么
事务(Transaction)是并发控制的基本单位。它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。例如,银行转账工作:从一个账号扣款并使另一个账号增款,这两个操作要么都执行。要么都不执行,在关系数据库中,一个事务可以是一条SQL语句、一组SQL语句或整个程序。所以,应该把他们看成一个事务。事务是数据库维护数据一致性的单位,在每个事务结束是,都能保持数据一致性。
事务语句
在关系数据库中,一个事务可以是一条SQL语句、一组SQL语句或整个程序。
开始事务:BEGIN TRANSACTION
提交事务:COMMIT TRANSACTION
回滚事务:ROLLBACK TRANSACTION
事务的四大特性
-
原子性(Atomicity)
是指事务是一个不可分割的工作单元,事务中的操作要么都发生,要么都不发生。
eg:张三给李四转钱,要么张三的钱减少李四的增多,要么两个人的钱都不变。 -
一致性(Consistency)
是指事务前后数据的完整性要保持一致。
eg:本来 张三有1000元 李四有1000元 一共2000。张三给李四转账100元,成功:张三900元,李四1100元 一共2000元。 -
隔离性(Isolation)
是指是指多个用户并发访问数据库的时候,一个用户的事务不能被其他用户的事务所干扰,多个并发事务之间数要相互隔离。 -
持久性(Durability)
是指一个事务一旦提交,他对数据库中数据的改变就是就是永久性的。
eg:张三 1000 李四 1000 张三给李四转100 张三提交了,数据回滚不了了
若不考虑隔离性,会发生的几种问题
1. 脏读
脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。
eg:用户A向用户B转账100元,对应SQL命令如下当只执行第一条SQL时,A通知B查看账户,B发现确实钱已到账(此时即发生了脏读),而之后无论第二条SQL是否执行,只要该事务不提交,则所有操作都将回滚,那么当B以后再次查看账户时就会发现钱其实并没有转。
update account set money=money+100 where name=’B’; (此时A通知B)
update account set money=money - 100 where name=’A’;
2. 不可重复读
不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。
eg:例如事务T1在读取某一数据,而事务T2立马修改了这个数据并且提交事务给数据库,事务T1再次读取该数据就得到了不同的结果,发生了不可重复读。
不可重复读和脏读的区别是,脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。
3. 虚读(幻读)
幻读是事务非独立执行时发生的一种现象。例如事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读。
通过设置事务隔离级别来解决读的问题
- 串行化(Serializable):可避免 脏读、不可重复读、虚读
- 可重复读(Repeatable read):可避免 脏读、不可重复读 。Mysql默认隔离级别
- 读已提交(Read committed):可避免 脏读 。Oracle默认隔离级别
- 读未提交(Read uncommitted):最低级别,上述情况都不能避免