事务:一组具有明确边界的执行过程,例如:张三给李四转钱
事务技术,是企业应用开发过程中不可缺少一门技术,主要用来确保在操作数据的时候,保证数据的完整性与一致性。
通常在WEB项目中,如果讲事务,那么事务就是一个请求,因为这个请求就正对一个执行过程
如果按照类型来分,事务可以分为:逻辑事务,物理事务
逻辑事务:也叫做业务事务,通常是为了保证业务逻辑的统一成功
物理事务:也叫做数据库事务,主要是为了保证数据的准确性
事务具有以下这4个特性,ACID:
A、原子性:事务是一个整体,它是密不可分的,具有原子的特性,要么都成功,要么都失败,不可能存在一部分成功,一部分失败的情况
B、一致性:事务一旦开启,处理事务的这整个过程中,数据满足(质量守恒),入多少,出多少,换句话说就是讲究的数据的准确性
C、隔离性:多个事务如果同时处理同一数据的时候,是互不干扰的,相互之间应该没有任何影响,目的是为了防止数据被破坏
D、持久性:事务一旦提交,那么它的结果就应该具有持久性,不应该再次被同一事务进行破坏,而应该持久化到数据库中
事务的隔离,要求事务必须在它处理完了之后,其他事务才可以处理相同的数据,如果我们大家在开发过程中,严格的遵循事务的隔离性的话,虽然我们保证了数据的准确性,但是我们牺牲整个项目的性能
这个时候,我们要在数据的准确性(空间)与项目的反应性能上(时间)做综合的权衡,也叫做“时空转换”
严格遵循隔离型,肯定不可取,我们必须要放松事务的隔离原则
隔离原则的级别:
可串行化(Serializable)
Serializable是事务隔离级别中最高级别,它绝对可以保证你的数据的准确性,其他的隔离级别都会在不同程度上允许数据的不一致。它的实现原理接近于对数据加锁
可重复读(RepeatableRead)-----使用最为广泛的一种
它的隔离级别仅次于可串行化,但是它有一个问题,它会造成数据的幻读,给操作者造成一种不应该
有的幻觉。所谓的幻读也就是指当前事务不是独立执行的时候发生的情况,例如:有两个事务同时需要对同一张表的数据进行修改,如A操作了表中的一部分数据,例如修改了工资从3K到5K,并且做了提交,但是尚未查询之前,B在表中新增了一条工资仍旧为3K的数据,并做了提交。A如果继续查询的话,将会发现它得到的数据中有一条工资依旧是3K的数据,它就会幻想是否是它没修改完!
读已提交(ReadCommitted)
它的隔离级别仅次于可重复读,但是它也会有一个问题,它会造成不可重复读,所谓的不可重复读是指数据库访问的过程中,同一个事务范围内两次查询的结果不一致,例如:在一个事务中,多次读取同一数据,在这个事务还没有结束的时候,例外一个事务同样访问了该数据,并且做了一定的修改,那么第一个事务再次读取这个数据的时候,两次获取的结果将不一样,对于数据库而言,不可重复读远比幻读来的容易,所以我们在工作中使用更多的是可重复读。
读未提交(ReadUncommitted)
它的隔离级别最低,开发过程中,谁用谁完蛋,它的问题是它会造成脏读,事务在处理的时候,可以读取其它事务尚未提交的数据,来做开发。脏读也叫做无效数据的读取,在系统中,根据无效数据做出的操作是不正确的。
总结:如何保证数据的准确性,以及如何保证系统的灵活性,需要各位看官综合权衡,小编言尽至此
事务的传播:当多个同时具有事务控制能力的Service的实现类方法互调的时候,所形成的事务边界控制问题。在spring框架中常见的事务边界控制,也就是传播特性有以下7种:
(1)、REQUERED
支持当前事务,如果当前没有事务,新建一个事务---------最为常见(CUD)
(2)、SUPPORTS
支持当前事务,如果没有事务,就按照非事务方式执行,通常在查询的时候使用最为广泛
(3)、MANDATORY
支持前事务,如果没有事务,就抛出异常
(4)、REQUERED-NEW
无论有没有事务,都新建一个新的事务,并且按照新事务来执行,将老事务挂起
(5)、NOT-SUPPORTS
以非事务方式执行,如果有事务,就将事务挂起
(6)、NEVER
绝对不能在事务范围内执行,如果有事务,就将事务挂起,只有该方法没有关联到任何事务,才能正常执行
(7)、NESTED
如果调用者与被调用者都还有事务,就将被调用者的事务包含在调用者的事务中,如果没有,就跟1的处理方式一样。