就是说事务里的所有操作要么全部做完,要么都不做,事务成功的条件是事务里的所有操作都成功,只要有一个操作失败,整个事务就失败,需要回滚。
举例:银行转账,从A账户转10元至B账户,需要经过两个步骤:
1)从A账户取10元;
2)存入10元至B账户。
注意:这两步要么一起完成,要么一起不完成,如果只完成第一步,第二步失败,A账号的钱会莫名其妙少了100元。
就是说数据库要一直处于一致的状态,事务的运行不会改变数据库原本的一致性约束。
举例:现有完整性约束a+b=100,如果一个事务改变了a,那么必须得改变b,使得事务结束后依然满足a+b=100,否则事务失败。
独立性是指并发的事务之间不会互相影响,如果一个事务要访问的数据正在被另外一个事务修改,只要另外一个事务未提交,它所访问的数据就不受未提交事务的影响。
比如现有有个交易是从A账户转10元至B账户,在这个交易还未完成的情况下,如果此时B查询自己的账户,是看不到新增加的10元的。
持久性是指一旦事务提交后,它所做的修改将会永久的保存在数据库上,即使出现宕机也不会丢失。
①说明:一个事务可以读取另一个未提交事务的数据。
②可能出现问题:读脏数据。
③解决方法:Read committed 读提交,能解决脏读问题。
④举例:小李爸爸给小李100元零花钱,该钱已经打到小李的账号上了,但是事务没有提交,小李爸爸让小李查看下钱收到没,小李一看,哇,老爸出手真阔绰啊,给了我100元零花钱。当小李查看完钱的数量后,小李爸爸马上回滚了刚才没有提交的事务,然后将数字改为10元提交了。(在此为小李心疼三秒。)
①说明:一个事务要等到另一个失误提交之后才能区读取数据。
②可能出现问题:出现不可重复读(事务的两次读取到的数据大小不一样)。
③解决方法:Repeatable read
④举例:小李爸爸去超市购物,使用刷卡买单,第一次刷卡收费系统检测到该卡中余额足够支付小李爸爸买的东西,但是捣蛋鬼小李,在这中间用小李妈妈的手机把小李爸爸卡里的钱都拿来买巧克力了,并且将订单提交了,事务提交完了。于是,当刷卡收费系统第二次检测小李爸爸卡得余额时,发现卡里没有钱。
①说明:开始读取数据(事务开启)时,不再允许修改操作。
②可能出现问题:幻读
③解决方法:Serializable,但是大部分情况使用使用加锁(乐观锁和悲观锁)读来进行保证。
④举例:小李爸爸查看自己昨天的消费情况,发现昨天确实消费了100元(事务开启),但是这时候,小李拿着他得手机给自己买了一条裤子,花了100元,也就是insert了一条心得消费记录,并提交。当小李爸爸打印自己的消费情况的时候,突然多了发现自己花了100元,这就是幻读。
①说明:事务串行化顺序执行。
②优点:可以避免脏读、不可重复读(针对update和delete)、幻读(针对insert)
③缺点:但是该事务隔离级别下,效率低下,不建议使用
注意:①MySQL的默认隔离级别是Repeatable read(可重复读)。
②SQLServer、Oracle的默认隔离级别是READ COMMITTED(读已提交)
1)select @@tx_isolation; 查看当前会话隔离级别
2)select @@global.tx_isolation; 查看系统当前隔离级别
3)set session transaction isolatin level read committed; 设置当前会话隔离级别
4)set global transaction isolation level read committed; 设置系统当前隔离级别
1)dbcc useroptions isolation level 查看系统当前隔离级别
2)set transaction isolation level Read UnCommitted; 设置系统当前隔离级别