Pro Spring 3读书笔记(三) - 18965050/pro-spring-3 GitHub Wiki
事务的ACID特性回顾:
- 原子性(Atomicity):即事务是不可分割的最小工作单元,事务内的操作要么全做,要么全不做
- 一致性(Consistency):在事务执行前数据库的数据处于正确的状态,而事务执行完成后数据库的数据还是处于正确的状态,即数据完整性约束没有被破坏;如银行转帐,A转帐给B,必须保证A的钱一定转给B,一定不会出现A的钱转了但B没收到,否则数据库的数据就处于不一致(不正确)的状态
- 隔离性(Isolation):并发事务执行之间无影响,在一个事务内部的操作对其他事务是不产生影响,这需要事务隔离级别来指定隔离性
- 持久性(Durability):事务一旦执行成功,它对数据库的数据的改变必须是永久的,不会因比如遇到系统故障或断电造成数据不一致或丢失
事务并发操作问题回顾:
- 丢失更新:两个事务同时更新一行数据,最后一个事务的更新会覆盖掉第一个事务的更新,从而导致第一个事务更新的数据丢失,这是由于没有加锁造成的
- 脏读:一个事务看到了另一个事务未提交的更新数据
- 不可重复读:在同一事务中,多次读取同一数据却返回不同的结果;也就是有其他事务更改了这些数据
- 幻读:一个事务在执行过程中读取到了另一个事务已提交的插入数据;即在第一个事务开始时读取到一批数据,但此后另一个事务又插入了新数据并提交,此时第一个事务又读取这批数据但发现多了一条,即好像发生幻觉一样
事务隔离级别回顾:
- 未提交读(Read Uncommitted):最低隔离级别,一个事务能读取到别的事务未提交的更新数据,很不安全,可能出现丢失更新、脏读、不可重复读、幻读
- 提交读(Read Committed):一个事务能读取到别的事务提交的更新数据,不能看到未提交的更新数据,不可能可能出现丢失更新、脏读,但可能出现不可重复读、幻读
- 可重复读(Repeatable Read):保证同一事务中先后执行的多次查询将返回同一结果,不受其他事务影响,不可能出现丢失更新、脏读、不可重复读,但可能出现幻读
- 序列化(Serializable):最高隔离级别,不允许事务并发执行,而必须串行化执行,最安全,不可能出现更新、脏读、不可重复读、幻读
隔离级别越高,数据库事务并发执行性能越差,能处理的操作越少。因此在实际项目开发中为了考虑并发性能一般使用提交读隔离级别,它能避免丢失更新和脏读,尽管不可重复读和幻读不能避免,但可以在可能出现的场合使用悲观锁或乐观锁来解决这些问题
Spring对于不同的数据访问框架(如Hibernate,iBatis/MyBatis)通过实现策略接口PlatformTransactionManager,从而能支持各种数据访问框架的事务管理.
public interface PlatformTransactionManager {
//获取或新生成一个事务状态
TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
void commit(TransactionStatus status) throws TransactionException;
void rollback(TransactionStatus status) throws TransactionException;
}
TransactionDefinition: 事务定义. 用于设置事务的隔离级别,事务的传播行为, 事务超时等属性.默认实现为DefaultTransactionDefinition
TransactionStatus: 事务状态.用于事务处理
Spring提供了许多内置事务管理器实现:
- DataSourceTransactionManager:位于org.springframework.jdbc.datasource包中,数据源事务管理器,提供对单个javax.sql.DataSource事务管理,用于Spring JDBC抽象框架、iBATIS或MyBatis框架的事务管理
- JdoTransactionManager:位于org.springframework.orm.jdo包中,提供对单个javax.jdo.PersistenceManagerFactory事务管理,用于集成JDO框架时的事务管理
- JpaTransactionManager:位于org.springframework.orm.jpa包中,提供对单个javax.persistence.EntityManagerFactory事务支持,用于集成JPA实现框架时的事务管理
- HibernateTransactionManager:位于org.springframework.orm.hibernate3包中,提供对单个org.hibernate.SessionFactory事务支持,用于集成Hibernate框架时的事务管理;该事务管理器只支持Hibernate3+版本,且Spring3.0+版本只支持Hibernate 3.2+版本
- JtaTransactionManager:位于org.springframework.transaction.jta包中,提供对分布式事务管理的支持,并将事务管理委托给Java EE应用服务器事务管理器
- OC4JjtaTransactionManager:位于org.springframework.transaction.jta包中,Spring提供的对OC4J10.1.3+应用服务器事务管理器的适配器,此适配器用于对应用服务器提供的高级事务的支持
- WebSphereUowTransactionManager:位于org.springframework.transaction.jta包中,Spring提供的对WebSphere 6.0+应用服务器事务管理器的适配器,此适配器用于对应用服务器提供的高级事务的支持
- WebLogicJtaTransactionManager:位于org.springframework.transaction.jta包中,Spring提供的对WebLogic 8.1+应用服务器事务管理器的适配器,此适配器用于对应用服务器提供的高级事务的支持
TransactionDefinition用于定义事务属性.包括
- 隔离级别:
- ISOLATION_DEFAULT:默认隔离级别,即使用底层数据库默认的隔离级别
- ISOLATION_READ_UNCOMMITTED:未提交读
- ISOLATION_READ_COMMITTED:提交读,一般情况下我们使用这个
- ISOLATION_REPEATABLE_READ:可重复读
- ISOLATION_SERIALIZABLE:序列化
- 事务传播行为:
- PROPAGATION_REQUIRED: 必须有逻辑事务,否则新建一个事务,使用PROPAGATION_REQUIRED指定,表示如果当前存在一个逻辑事务,则加入该逻辑事务,否则将新建一个逻辑事务
- PROPAGATION_REQUIRES_NEW: 创建新的逻辑事务,使用PROPAGATION_REQUIRES_NEW指定,表示每次都创建新的逻辑事务
- PROPAGATION_SUPPORTS: 指如果当前存在逻辑事务,就加入到该逻辑事务,如果当前没有逻辑事务,就以非事务方式执行
- PROPAGATION_NOT_SUPPORTED: 不支持事务,如果当前存在事务则暂停该事务,使用PROPAGATION_NOT_SUPPORTED指定,即以非事务方式执行,如果当前存在逻辑事务,就把当前事务暂停,以非事务方式执行
- PROPAGATION_MANDATORY: 必须有事务,否则抛出异常
- PROPAGATION_NEVER: 不支持事务,如果当前存在是事务则抛出异常
- PROPAGATION_NESTED: 如果当前存在事务,则在嵌套事务内执行,如果当前不存在事务,则创建一个新的事务,嵌套事务使用数据库中的保存点来实现,即嵌套事务回滚不影响外部事务,但外部事务回滚将导致嵌套事务回滚
TransactionTemplate继承自DefaultTransactionDefinition(事务隔离级别为默认交由底层数据库支持, 事务传播行为是PROPAGATION_REQUIRED,事务只读属性为false, 事务超时交由底层数据库支持),并封装了PlatformTransactionManager.事务执行交由TransactionCallback回调接口或TransactionCallbackWithoutResult来完成. 如果要回滚事务, 只需要TransactionStatus.setRollbackOnly(true)即可.
-
声明式事务
<tx:advice id="……" transaction-manager="……"> <tx:attributes> <tx:method name="……" propagation=" REQUIRED" isolation="READ_COMMITTED" timeout="-1" read-only="false" no-rollback-for="" rollback-for=""/> …… </tx:attributes> </tx:advice>
-
注解式事务
- 启动注解式事务.配置文件配置:
<tx:annotation-driven transaction-manager="txManager"/>
- @Transactional
- 启动注解式事务.配置文件配置: