事务处理
事务的4个基本特征
1.Atomic(原子性),事务中包含的操作被看做是一个整体的业务单元,这个业务单元中的操作要么全部成功,要么全部失败,不会出现部分成功,部分失败的场景。
2.Consistency(一致性),事务在完成时,必须使所有的数据都保持一致的状态,在数据库中所有的修改都基于事务,保证了数据的完成性。
3.Isocation(隔离性),多个应用程序线程同时访问同一个数据,在不同的事务中被访问,这样就会产生丢失更新。为了在不同程度上压制丢失更新的产生,数据库定义了隔离级别的概念。因为互联网应用是高并发场景,所以隔离性是要重点掌握的内容。
4.Durability(持久性),事务结束后,所有的数据都固化到一个地方,比如保存到磁盘或数据库中,即使断电重启后也能再次提供给程序访问。
数据库的隔离级别
1.未提交读(read uncommitted),允许一个事务读取另一个事务没有提交的数据,未提交读是一种危险的隔离级别,所以一般在实际的开发中用的很少,优点是并发能力高,适合那些对数据的一致性没有要求而追求高并发的场景。最大的坏处就是会出现脏读。为了克服脏读,提出了读写提交的隔离级别。
2.读写提交(read committed),是指一个事务只能读取另外一个事务已经提交的数据,不能读取未提交的数据,从而克服脏读的问题。但是读写提交的坏处就是出现不可重复读,为了克服不可重复读,提出了可重复读的隔离级别。
3.可重复读(repeatable read),为了克服在读写提交的时候出现的不可重复读问题,因为在读写提交的时候,可能出现一些值的变化,影响当前事务的执行。但是假设商品正在交易,后台有人在进行查询分析和打印的业务,这时就会出现一个新的问题就是幻读。
4.串行化(Serializable),是数据库最高的隔离级别,它会要求所有的 Sql 都按照顺序执行,这样就可以克服脏读、不可重复读、幻读的问题,能够完全保证数据的一致性,但是性能是最差的。
事务的传播行为(最常用的:REQUIRED、REQUIRES_NEW、NESTED)
1.REQUIRED(默认的传播行为,如果当前存在事务,就沿用当前的事务,如果当前不存在事务,就创建一个事务运行业务)
2.SUPPORTS(支持事务,如果当前存在事务,就沿用当前事务,如果当前不存在事务,就继续采用无事务方式运行)
3.MANDATORY(必须使用事务,如果当前没有事务,就抛出异常,如果当前存在事务,就沿用当前事务)
4.REQUIRES_NEW(无论当前是否存在事务,都会创建一个新事务运行业务,新的事务就拥有独立的锁和隔离级别等特性,与当前事务相互独立)
5.NOT_SUPPORTED(不支持事务,当前存在事务时,将挂起事务,运行方法)
6.NEVER(不支持事务,如果当前存在事务,就抛出异常,否则继续使用无事务机制运行)
7.NESTED(嵌套事务,如果被父方法调用,子方法发生异常,在父方法中 try catch 子方法,那么只回滚子方法,不回滚父方法已经执行的,后面的语句也可以继续执行)
同一个 Service 类中的方法的自调用,会引起子方法的 @Transactional 失效!!!