Spring中的声明式事务是基于AOP实现的,而Spring的AOP是以方法为单位的,所以Spring的事务属性就对事务应用到方法上的策略描述,这些属性为:传播行为,隔离级别,只读和超时属性。
1、从Spring容器中获取PlatformTransactionManager实例。
2、定义TransactionDefinition并设置好事务的隔离级别和传播方式。
3、通过PlatformTransactionManager.getTransaction()开始一个事务,并获得TransactionStatus对象。
4、运行需要在事务环境下执行的代码并捕获异常。
5、如果有异常发生,将TransactionStatus设置为setRollbackOnly(),表示要回滚事务。
6、调用PlatformTransactionManager.commit(TransactionStatus)方法提交事务,Spring根据TransactionStatus的状态决定如何提交事务。如果TransactionStatus设置为setRollbackOnly(),则回滚事务,否则提交
Spring的事务管理器有5个,都实现了PlatformTransactionManager接口,如下所示:
DataSourceTransactionManager JDBC事务管理器
HibernateTransactionManager Hibernate事务管理器
JdoTransactionManager JDO事务管理器
JtaTransactionManager JTA事务管理器
PersistenceBrokerTransactionManager Apache的OJB事务管理器
事务的ACID特性
事务使用ACID特性来衡量事务的质量。介绍如下:
1,原子性
事务必须是原子的,在事务结束的时候,事务中的所有任务必须全部成功完成,否则全部失败,事务回滚到事务开始之间的状态。
2,一致性
事务必须保证和数据库的一致性,即数据库中的所有数据和现实保持一致。如果事务失败数据必须返回到事务执行之前的状态,反之修改数据和现实的同步。
3,隔离性
隔离性是事务与事务之间的屏障,每个事务必须与其他事务的执行结果隔离开,直到该事务执行完毕,它保证了事务的访问的任何数据不会受其他事务执行结果的影响。
4,持久性
如果事务成功执行,无论系统发生任何情况,事务的持久性都必须保证事务的执行结果是永久的。
事务之间的缺陷
在事务处理中有违返ACID特性的3个问题:脏读取,不可重复读和幻读行。如果存在多个并发事务在运行,而这种事务操作了同一个数据来完成它们的任务,就会导致3个问题的存生。要解决它们,就必须在事务之间定义合适的隔离级别。
为保证事务的完整性,必须解决事务之间可能存在的3个问题。
(1)脏读取
一个事务读取了另一个未提交的并行事务写的数据。
当一个事务读取了另一个事务尚未提交的更新,就叫脏读取。在另一个事务回滚的情况下,当前事务所读取的另一个事务的数据就是无效的。
(2)不可重复读取
一个事务重新读取前面读取过的数据, 发现该数据已经被另一个已提交的事务修改过.
在一个事务中执行多次同样的查询操作,但每次查询的结果都不一样,就叫做不可重复读取,通常这种情况是由于数据在二次查询之间被另一个并发的事务所修改。
(3)幻影行
一个事务重新执行一个查询,返回一套符合查询条件的行, 发现这些行因为其他最近提交的事务而发生了改变
这是对事务危害最小的一个问候,它类似不可重复读取,也是一个事务的更新结果影响到另一个事务问题。但是它不仅影响另一个事务查询结果,而且还会使查询语句返回一些不同的行录行。
这3个问题危害程度依次为:脏读取最大-->不可重复读取-->幻影行最小。
认识Spring的事务包的API