什么是事务?
事务就是一组具有明确边界的序列,是企业应用中不可缺少的一种技术,它是用来确保一组操作的数据的完整性和一致性。
如:张三给李四赚钱,这个过程就是一个事务,通常在WEB应用中,一个请求就对应一个事务。
事务按照其类型可以分为:
1. 逻辑事务,是为了保证业务逻辑的成功性。
2. 物理事务,是为了保证数据的准确性。
事务特性:
1、原子性,事务的整个过程不可再分,具有原子特性,要么都成功,要么都失败。
2、一致性,一旦事务进行,处理事务的整个过程中,数据满足(质量守恒法则),入多少,就出多少。
3、隔离性,多个事务同时处理一个数据的时候,事务之间互不影响,防止数据被破坏。
4、持久性,一个事务被成功处理,它的结果就是既定的事实,不应该再次受到同一事务的破坏,应该被持久到DB中。
在Spring框架中 ,关于事务,有2种处理方式:
1、编程式事务,将事务管理代码嵌入到业务逻辑的方法中来控制事务的提交或回滚。通常在编程式事务中,必须在每个业务操作的方法中都包含有额外的事务管理代码。
2、声明式事务,在企业应用开发中,声明式事务最为常见,比编程式事务管理更好用。它将事务管理代码从业务操作的方法中分离开来,在配置文件中给予声明。事务管理作为一种横切关注点,通过AOP来管理事务。
事务的传播,当多个具有事务控制的Service实现类的方法互调时,所形成的复杂的事务边界控制问题。
Spring框架中常见的事务传播控制类型有以下7种:
(调用者-----被调用者,支持当前事务,是指调用者含有事务,那么被调用者就按照当前事务执行。)
1、REQUERED
支持当前事务,如果没有事务,就新建一个事务--------------最为常用(CUD)
2、SUPPORTS
支持当前事务,如果没有事务,就按照非事务方式进行处理,通常在查询时使用。
3、MANDATORY
支持当前事务,如果没有事务,就抛出异常。
4、REQUERED-NEW
无论有没有事务,都新建一个事务,如果已有事务,就将事务挂起,按照新事物执行。
5、NOT-SUPPORTS
以非事务方式进行,如果已有事务,就将事务挂起。
6、NEVER
以非事务方式进行,如果已有事务,就将事务挂起。
7、NESTED
如果有被调用者也含有事务,就将该事务嵌套到调用者的事务中,如果没有,就和1的处理方式一样。
事务的隔离,要求事务必须在它处理成功之后,它的处理结果其他事务才可见。如果我们在系统中严格按照隔离性,确实能保证数据的准确性。并且事务是按照可串行的方式依次执行。但是过度串行的结果就是性能的低下。为了保证数据的准确性,以及保证系统的处理性能的灵活性,需要根据具体的情况,选择具体的事务隔离级别,从而做到风险与性能之间的平衡。
事务的隔离级别有:
1、可串行化(Serializable)
可串行化不能保证你得到什么,但是可以保证你得到的绝对是准确的。它是隔离级别中最高的级别。其他的每个级别都不同程度上允许不一致读。
2、可重复读(Repeatable read)------使用较为广泛
可重复读,它的隔离级别仅次于可串行化,但是有一个问题就是,它会造成幻读,给操作者造成一种不应该有的幻觉。所谓幻读是指当前事务不是独立执行时发生的情况,例如:有两个事务同时对一张表进行修改,比如修改表中的“全部数据行”并且提交,但是在它修改后,尚未再次查询时,还存在例外一个事务也在修改这个表中的数据,例如插入“一行新数据”。那么,第一个操作者在查询时,就会感觉表中依旧还有尚未修改完的数据。
3、读已提交(Read committed)
读已提交,它的隔离级别仅次于可重复读,但是它也同样有一个问题就是:它允许不可重复度,所谓的不可重复读是指数据库访问的过程中,一个事务范围内两次查询结果不一致。在一个事务中,多次读取同一数据,在这个事务还没有结束时,例外一个事务也访问该数据。并且做出了修改,从而导致第一个事务两次获取不一样。对于数据库而言,不可重复度要比幻读来的更容易一些。因此可重复读比读已提交有更好的正确性,但是相对而言,灵活度较低,所以可重复读在项目中使用较为广泛。(可重复度只是发生的是修改后的读取幻像,而读已提交则可能发生重复读取后的修改问题),
4、读未提交(Read uncommitted)
读未提交,隔离级别最低,在项目中,几乎没有使用,其原因是它允许脏读。事务在处理的时候,可以读取其他事务尚未提交的数据。脏读又叫无效数据的读出,在系统中,依据无效数据做出的操作是不正确的。
如何保证正确性,以及如何保证系统的灵活性,需要多方面权衡。
注:本文由 http://blog.csdn.net/pu_xubo565599455 总结。