Spring事务管理三:编程式事务

前边提到,编写程序式的事务管理可以清楚的定义事务的边界,可以实现细粒度的事务控制,比如你可以通过程序代码来控制你的事务何时开始,何时结束等,它可以实现细粒度的事务控制。 1. TransactionTemplate Spring提供了TransactionTemplate对象来控制事务,它使用了一种回调机制,通过回调来修改事务状态,继承关系如下: TransactionOperations接口定义了基础的事务的执行操作execute(),该接口便于后续扩展,一般不直接使用。 在使用TransactionTemplate之前,需要声明bean: <!--JDBC事务管理器--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!--编程式事务配置--> <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"> <property name="transactionManager" ref="transactionManager"/> </bean> TransactionTemplate使用PlatformTransactionManager的实现来管理事务,这里注入的是JDBC的事务管理器。事务控制代码如下: public void add(User user) throws Exception{ // Spring编码式事务,回调机制 transactionTemplate.execute(new TransactionCallback<Object>() { @Override public Object doInTransaction(TransactionStatus status) { try { userMapper.insertSelective(user); } catch (Exception e) { // 异常,设置为回滚 status.setRollbackOnly(); throw e; } return null; } }); } 调用TransactionTemplate的execute()方法,传递一个TransactionCallback接口的实现,执行其doInTransaction()方法,该方法会回传事务状态对象TransactionStatus,如果有异常,则调用status.setRollbackOnly()将事务状态标记为回滚,否则doInTransaction方法正常返回,事务则会提交。 如果事务控制的方法不需要返回值,那么可以使用TransactionCallback接口的抽象实现类TransactionCallbackWithoutResult: @Override public void add(User user) throws Exception { // Spring编码式事务,回调机制 transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) { try { userMapper.insertSelective(user); } catch (Exception e) { // 异常,设置为回滚 status.setRollbackOnly(); throw e; } } }); } ...

2018-03-08 · 1 min · 103 words · Hank

Spring事务管理二:Spring事务管理器

前边简单介绍了事务的概念和其ACID特性,现在让我们看看Spring是如何实现对事务的支持的。 1. Spring事务管理器结构 Spring并不直接管理事务,而是提供多种事务管理器,将管理事务的责任委托给JTA或相应的持久性机制所提供的某个特定平台的事务实现。 Spring对事务管理器的抽象: Spring提供了顶层接口PlatformTransactionManager,并提供了扩展接口ResourceTransactionManager和抽象实现类AbstractPlatformTransactionManager。PlatformTransactionManager下的所有接口和实现类如图所示: 一般而言,每一种事务实现的类图如下: PlatformTransactionManager是Spring事务管理器的核心,接口定义如下: public interface PlatformTransactionManager { // 返回一个已经激活的事务或创建一个新的事务(根据给定的TransactionDefinition类型参数定义的事务属性), // 返回的是TransactionStatus对象代表了当前事务的状态,其中该方法抛出TransactionException(未检查异常) // 表示事务由于某种原因失败。 TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException; // 提交给定的事务,检查其状态。如果事务被标记为rollback-only,则执行回滚。 // 如果事务不是新的事务,则忽略提交周围适当的事务。如果先前的事务被挂起,则在提交新事务后恢复先前的事务。 void commit(TransactionStatus status) throws TransactionException; // 执行给定事务的回滚。如果事务不是一个新的事务,将其周边适当的事务标记为rollback-only。 // 如果先前的事务被挂起,则在回滚新事务后恢复先前的事务。 void rollback(TransactionStatus status) throws TransactionException; } TransactionDefinition接口定义如下: public interface TransactionDefinition { // 返回事务传播行为 int getPropagationBehavior(); // 返回事务隔离级别 int getIsolationLevel(); // 返回事务超时时间 int getTimeout(); // 返回事务是否只读 boolean isReadOnly(); // 返回事务的名称 String getName(); } ...

2018-03-07 · 1 min · 200 words · Hank

Spring事务管理一:Spring事务简介

1. 定义 在软件开发领域, 全有或全无的操作被称为事务(transaction)。 事物允许将几个操作组合成一个要么全部发生要么全部不发生的工作单元。发生和不发生两者只能选择其一,而不可能两者都选择。事务确保了数据和资源免于处在不一致的状态。 让我们继续使用最简单有效的转账例子来说明事务: A给B转100元,这个过程大概需要两步: step1、从A的账户扣除100元; step2、给B的账户增加100元。 这两步必须要么全部执行成功要么都不成功并且还原账户的金钱为初始值,否则转账失败。如果step1成功而step2失败,那么A账户少了100元,但是B却没收到钱;如果step1失败而step2成功,B账户会多出100元。这两种情况都是不允许发生的。 所以,step1和step2必须处于同一事务中,我们就说事务把这两个操作组合为要么都成功要么都失败的工作单元。整个操作成功,那么转账成功,结果是A账户扣了100元而B账户多了100元;如果整个过程失败,那么A和B的账户的金额恢复到转账前的状态,即未发生任何变化,就像转账操作从未发生过一样。 2. ACID特性 Atomic(原子性):确保所有操作要么都发生,要么都不发生。 Consistent(一致性):事务前后,数据均处于正确状态,数据不应该被破坏。 Isolated(隔离性):事务彼此隔离,用户间操作不相混淆。 Durable(持久性):事务一旦完成,结果应该持久化,例如保存到数据库中。 上边转账的例子中,两步操作必须要么成功要么都失败,确保了原子性;而原子性保证账户中的金额不会处于不一致或者说部分完成,保证了一致性;转账过程与其他转账过程互不影响,遵循隔离性;转账成功后,结果必须持久化保存,防止事务结果丢失。 3. Spring对事务管理的支持 Spring提供两者事务管理方式:编程式事务管理和声明式事务管理。 3.1. 编程式事务管理 编写程序式的事务管理可以清楚的定义事务的边界,可以 实现细粒度的事务控制,比如你可以通过程序代码来控制你的事务何时开始,何时结束等,与后面介绍的声明式事务管理相比,它可以实现细粒度的事务控制。 3.2. 声明式事务管理 如果你并不需要细粒度的事务控制,你可以使用声明式事务,在Spring中,你只需要在Spring配置文件中做一些配置,即可将操作纳入到事务管理中, 解除了和代码的耦合, 这是 对应用代码影响最小的选择,从这一点再次验证了Spring关于 AOP的概念。当你不需要事务管理的时候,可以直接从Spring配置文件中移除该设置。 Spring通过回调机制将实际的事务实现从事务性代码中抽象出来。如果应用只使用一种持久化资源,那么可以使用持久化机制本身的事务性支持(JDBC、Hibernate、JPA等);如果应用事务跨多个资源,那么Spring会使用第三方的JTA(JAVA事务API)实现来支持分布式(XA)事务。 使用声明式事务还是编程式事务管理,在很大程度上是 细粒度和易用性之间权衡。一般情况下,不需要精确控制事务,采用声明式事务不仅易用性高,而且降低了事务与其他业务代码的耦合性。 4. 总结 在软件开发领域,全有或全无的操作被称为事务。事务必须具备ACID特性,在Spring中,除了编程来精确控制事务,还可以使用AOP来配置低耦合度的声明式事务控制。

2018-03-07 · 1 min · 38 words · Hank