事务是并发控制的单位,是数据库的逻辑工作单位,是用户为了保证对同一数据操作的一致性定义的一个操作序列,是一个不可分割的工作单位。通过事务,Sql Server能将逻辑相关的一组操作绑定在一起,方便服务器保持数据的完整性。
事务特性(ACID)
1、原子性(Atomicity)
事务中的操作要么全做,要么全不做。
2、一致性(Consistency)
事务在开始之前和结束之后,数据都没有被破坏。
3、隔离型(Isolation)
一个事务的执行不能被其他事务干扰。
4、持久性(Durability)
一个事务一旦提交,它对数据库中数据的改变就是永久性的,且不可回滚。
事务并发操作引起的问题
多个事务并发运行,经常会操作相同的事务来完成各自的任务,所以——并发是必须的
1、脏读(Dirty Reads)
一个事务读取了另一个事务修改单尚未提交的数据时。如果这个修改在稍后被回滚,那么第一个事务获取的数据是无效的。
2、幻读(Phantom Read)【 幻读与不可重复读类似 】
操作同一个事务,不同时间段读取同一数据,读到的内容不同
B在读取A事务的同时,A事务正在进行insert操作,当A事务执行完insert操作并提交给数据库后,B事务获取到的数据变成A事务insert后的数据
3、不可重复读(Nonrepeatable read)
一个事务范围内两个相同的查询返回了不同的数据
若有A事务对数据进行update操作时,B操作事务要等待这个update操作提交后才能读取A 的数据
幻读重点在于插入与删除,不可重复读重点在于修改
不可重复读和脏读的区别:脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。
事务的隔离级别
隔离级别定义了一个事务可能受其他并发事务影响的程度
1、读未提交(Read uncommited),最低级别,任何情况都无法保证。
一个事务可以读取另一个未提交事务的数据
2、读已提交(Read committed)可避免脏读的发生,是项目中常用的,Oracle默认的隔离级别
一个事务要等另一个事务操作完成后才能读取数据
3、可重复读(Repeatable)可以避免脏读、不可重复读的发生,MySQL默认的隔离级别
在开始读取数据(事务开启)时,不允许再进行修改操作
4、串行化(Serializable)可以避免脏读、幻读、不可重复读的发生,他的隔离级别最高。
【 以上隔离级别从低到高 】
注:Oracle只支持Read committed 和 Serializable,MySQL支持以上所有隔离级别
级别越高,执行效率越低。像Serializable,就是以锁的方式使得其他线程只能在锁外等待。
查看MySQL的隔离级别:select @@tx_isolation
设置MySQL隔离级别:set session transaction isolation level
事务的传播行为
用于解决业务层方法之间的互相调用问题(propagation:传播)
1、PROPAGATION_REQUIRED:如果当前存在事务,就加入该事务;如果当前没有事务,则创建一个新的事务;(该设置是当前最常用的)
2、PROPAGATION_SUPPORTS:该方法不需要事务的上下文;但是如果存在当前事务,就在该事务中运行
3、PROPAGATION_REQUIRED_NEW:无论当前事务是否存在,都会创建新事务【如果存在当前事务,当前事务会被挂起】
4、PROPAGATION_MANDATORY:该方法必须在事务中运行,若当前事务不存在,会抛出一个异常
5、PROPAGATION_NOT_SUPPORTS:该方法不运行在事务中,若存在当前事务,当前事务会被挂起
6、PROPAGATION_NEVER:该方法不能运行在事务中,若当前有事务在运行,则会抛异常
7、PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务中执行(嵌套的事务可以独立于当前事务进行单独地提交或回滚);如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作