Spring事务的介绍
首先,事务管理是保证数据操作的事务性 ACID(即原子性、一致性、隔离性、持久性)。
对于使用支持事务管理的数据库时,普通的jdbc的连接没用配置事务也可以保存变更,原因在于连接的属性autocommit设置了true,即自动提交了事务。
而对于某些数据库本身没有对事务的支持,那么事务管理也是一纸空谈没有必要进行配置(有例外),如MySQL的MyISAM没有事务管理的支持。但是如果使用了有自身事务管理的框架如Hibernate的话可以变向地实现事务管理(由于Hibernate的一级缓存,我们在操作update和save等时,它不会向数据库提交数据,而是等我们调用commit或者flush一级缓存的数据时才会提交更改)。
所谓的事务的传播或者说嵌套通俗地说就是,事务方法的互相调用。spring提供了七中传播行为:
- PROPAGATION_REQUIRED 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
- PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。
- PROPAGATION_MANDATORY 使用当前的事务,如果当前没有事务,就抛出异常。
- PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。
- PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
- PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。
- PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与 PROPAGATION_REQUIRED 类似的操作。
Spring混合事务的管理
几个常用的事务管理器
Hibernate | Spring JDBC 或 iBatis | HibernateTransactionManager |
JPA | Spring JDBC 或 iBatis | JpaTransactionManager |
JDO | Spring JDBC 或 iBatis | JdoTransactionManage |
即使用jpa又使用jdbc(JPA+JDBC)称为混合事务,在Spring AOP的事务增强的情况下,混合事务仍然会保持事务的一致,即混合技术但唯一事务。
但是在使用Hibernate时由于一级缓存的存在必须flush()一级缓存,因为其他框架是感知不到他的一级缓存。
Spring的事务增强是在aop的基础上的,所以aop覆盖不到的方法即不能有Spring的事务管理。
- 基于接口的动态代理,除public外其他所有的方法都不能被覆盖包括 public static
- 基于cglib的动态代理,static、private、final都不能被覆盖
JDBC的连接泄露
获取的connection的方式很多,例如 datasource的获取,通过 DataSourceUtils获取,或者使用 TransactionAwareDataSourceProxy 获取 。后面两种获取方法在效果上是一致的所以归并为一类(后文称 B方法),而直接获取的是另一类(后文称为 A方法)。直接获取的,在事务管理方法中表现出开启两个连接(Spring在事务管理方法中存在一个事务上下文,并同一个数据源绑定唯一一个连接,所有事务上下文传播的方法共享这个链接,加上直接获取的连接即为两个连接同时开启),另一种则只是获取了该方法的事务连接所以表现出只开启了一个连接。直接获取的在方法执行完毕后会泄露一个连接,所以必须显式地关闭连接 connection.close()。B方法在存在事务上下文的情况下不必显式地关闭连接,但是没有事务的情况下由于获取方式其实也是直接datasource获取所以也必须显示地关闭连接。
JDBCTemplate内部也是使用 DataSourceUtils获取的连接,但是jdbcTemplate都作显式关闭以防没有上下文的情况。从另个侧面也说明了jdbcTemplate的连接跟事务连接是同一个,所以混合事务管理时才开启一个事务。
已有 0人发表留言,猛击->> 这里<<-参与讨论
ITeye推荐