事务可从多种层面进行分类,数据库角度、java角度、编程角度:

数据库角度

根据数据源的数量分为本地事务和全局事务

本地事务:普通事务,独立的一个数据库,保证在该数据库上操作的ACID。

分布式事务:涉及两个或多个数据库源的事务,即跨越多台同类或异类数据库的事务(由每台数据库的本地事务组成的),分布式事务旨在保证这些本地事务的所有操作的ACID,使事务可以跨越多台数据库;

 

java角度

根据规范分为JDBC事务和JTA事务

JDBC事务:普通事务,即数据库事务中的本地事务,通过connection对象控制管理。

JTA事务:JTA指Java事务API(Java Transaction API),是Java EE数据库事务规范, JTA只提供了事务管理接口,由应用程序服务器厂商(如WebSphere Application Server)提供实现,JTA事务比JDBC更强大,支持分布式事务(当然也支持本地事务)。

 

编程角度(Spring层面)

根据是否通过编程分为声明式事务和编程式事务

声明式事务:通过XML配置或者注解实现,更为简单

编程式事务:通过编程代码在业务逻辑时需要时自行实现,粒度更小。

详情可见:

 

备注:  声明式事务管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。

声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。

 

----------------------------------------------------------------------------------

 

接下来从Spring层面上,让我们总结一下事务的隔离级别和传播行为。

 

隔离级别

有5大隔离级别,这是在TransactionDefinition接口中定义的。

1、ISOLATION_DEFAULT:

用底层数据库的默认隔离级别,即数据库管理员设置成什么就是什么;

2、ISOLATION_READ_UNCOMMITTED(未提交可读):

最低隔离级别、事务未提交前,就可被其他事务读取(会出现幻读、脏读、不可重复读)

3、ISOLATION_READ_COMMITTED(提交可读):

一个事务提交后才能被其他事务读取到(会造成幻读、不可重复读)、sql server的默认级别

4、ISOLATION_REPEATABLE_READ(可重复读):

可重复读,保证多次读取同一个数据时,其值都和事务开始时候的内容是一致,禁止读取到别的事务未提交的数据(该隔离基本可防止脏读,不可重复读(重点在修改),但会出现幻读(重点在增加与删除))(MySql默认级别,更改可通过set

transaction isolation level 级别)

5、ISOLATION_SERIALIZABLE(序列化):

代价最高最可靠的隔离级别(该隔离级别能防止脏读、不可重复读、幻读)

 

默认为isolation_default(底层数据库默认级别),其他四个隔离级别跟数据库隔离级别一致。

 

备注:

幻读:同样的事务操作过程中,不同时间段多次(不同事务)读取同一数据,读取到的内容不一致(一般是行数变多或变少)。

不可重复读:同一事务中,多次读取内容不一致(一般行数不变,而内容变了)。

丢失更新:两个事务同时更新一行数据,最后一个事务的更新会覆盖掉第一个事务的更新,从而导致第一个事务更新的数据丢失,这是由于没有加锁造成的;

脏读:一个事务读取到另外一个未提及事务的内容,即为脏读。