事务的特性:
1、原子性:指事务是一个不可分割的单位,要么全都成功,要么全部失败;
2、一致性:事务操作前后数据的完整性保持一致(列:张三2000元、李四2000元,张三转给李四1000后,张三1000,李四3000,两人的总金额还是4000,保持了数据的完整性)
3、隔离性:一个事务在操作过程中不受到其他事务的影响;
4、持久性:一个事务如果已经提交,对数据的修改就是持久的,即使数据库发生故障也不应该对其有任何影响;
不考虑隔离性的话会引起:
1、脏读 : 一个事务读到另一个事务还未提交的事务
2、不可重复读:在同一事务中多次读到的数据不一致,有可能读到其他事务更新并提交的数据,就会导致前后不一致;
3、幻读(虚读):在事务A第一次查询之后,事务B删除或插入的方式修改事务A的结果集再提交,事务A再次查询就会产生结果不一致;
数据库的隔离级别:
1. Read UnCommitted(读未提交)
一个事务可以读取到另一个事务未提交的数据,可能会引发脏读、不可重复读、幻读;
2. Read Committed(读已提交)
一个事务的更新操作结果只有在该事务提交之后,另一个事务才可以的读取到同一笔数据更新后的结果。解决了脏读,可能会引发不可重复读、幻读;
3. Repeatable Read(重复读)
整个事务过程中,对同一笔数据的读取结果是相同的,不管其他事务是否在对共享数据进行更新,也不管更新提交与否,解决了脏读和不可重复读,可能会引发幻读。
4. Serializable(序列化)
最高隔离级别。所有事务操作依次顺序执行。解决了三种读问题,但这会导致并发度下降,性能最差。
mysql 默认隔离级别 重复读
oracle 默认隔离级别 读已提交
事务的传播行为:
使用场景:
事务的传播行为共有7种:常用的是标为红色的传播行为类型
1、PROPAGATION_REQUIRED : 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。即:调用service1的事务之后,在使用service2的事务之前,发现当前已有事务,则把service2加入到service1的事务中。
2、PROPAGATION_SUPPORTS :支持当前事务,如果当前没有事务,就以非事务方式执行。即:如果service1有事务,service2就使用当前事务,如果service1没有事务,service2以非事务方式执行;
3、PROPAGATION_MANDATORY : 使用当前的事务,如果当前没有事务,就抛出异常。即:如果service1有事务,service2就使用当前事务,如果service1没有事务,service2抛出异常;
1 、2 、3 都支持当前事务,在service1中没有事务的时候做的操作不同,1 是新建事务,2 是不使用事务,3 是抛出异常;
4、PROPAGATION_REQUIRES_NEW : 如果当前存在事务,把当前事务挂起,新建一个事务。即:service1中有事务,则挂起,service2不使用service1的事务,而是新建一个事务;
5、PROPAGATION_NOT_SUPPORTED : 总是以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。即:service1中有事务,则挂起,service2不使用事务;
6、PROPAGATION_NEVER : 以非事务方式执行,如果当前存在事务,则抛出异常。 即:service1中有事务,service2会抛出异常;
4 、5 、6 都不用当前事务,在service1中有事务的时候挂起,4 是新建事务,5 是不使用事务,6 是抛出异常;
7、PROPAGATION_NESTED : 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。在service1事务执行完后,可以设定一个保存点,service2如果发生异常,可以选择回滚到保存点,或回滚到初始状态。