Spring Transaction Management

参见官网16. Transaction Management

Spring Framework提供事务管理的抽象,具有以下优点:

  • 为多个事务api提供一致的编程模型,如:Java Transaction API(JTA)、JDBC、Hibernate、Java Persistence API(JPA)、Java Data Objects(JDO)
  • 支持 声明式事务(declarative transaction management)
  • 提供比JTA更简单的 编程式事务 api
  • 和Spring’s data access abstractions的完美整合

本文包含以下几个章节:

  1. Understanding the Spring Framework transaction abstraction: 给出了核心类,对从各种方式获取DataSource做出说明。
  2. Synchronizing resources with transactions: 说明了代码如何保证事务所需的资源被创建、重用、清除。
  3. Declarative transaction management: 编程式事务的支持。
  4. Programmatic transaction management: 编程式事务的支持。
  5. Transaction bound event : 说明了如何在事务中使用事件机制。

Understanding the Spring Framework transaction abstraction

PlatformTransactionManager

Spring事务抽象的关键是 transaction strategy 的概念。transaction strategy 定义在接口org.springframework.transaction.PlatformTransactionManager中:

public interface PlatformTransactionManager {

    TransactionStatus getTransaction(
            TransactionDefinition definition) throws TransactionException;

    void commit(TransactionStatus status) throws TransactionException;

    void rollback(TransactionStatus status) throws TransactionException;
}

该接口的实现可以通过spi机制或直接编码的方式引入IoC容器。无论是编程式事务还是声明式事务,该接口的实现都很重要。该接口方法抛出TransactionException的运行时异常。
#getTransaction方法入参TransactionDefinition返回TransactionStatus

TransactionStatus对象可以代表一个新的事务,或者一个已经存在的事务,JavaEE中TransactionStatus和执行线程绑定(ThreadLocal<TransactionInfo>)。

TransactionDefinition用来指定以下内容:

  • Isolation:隔离级别
  • Propagation:事务传播方式,如果一个事务已经存在,此时又有一个事务发生如何处理?
  • timeout:超时时间
  • Read-only status:只读状态

PlatformTransactionManager的实现过程通常需要了解其使用环境,如:JDBC JTA Hibernate …

Synchronizing resources with transactions

对于不同的transaction manager,该manager所需的资源如何关联以及同步到事务中。比如:DataSourceTransactionManager所需资源是DataSourceHibernateTransactionManager所需资源是SessionFactory
该节说明了代码是如何直接或间接地使用持久化api,如JDBC、Hibernate 、JDO,保证资源能够正确地被创建、重用、清除。
该节还说明了事务同步机制是如何通过PlatformTransactionManager被触发的。

Declarative transaction management

最常用的事务管理方式,对业务代码侵入较小。

使用方式为在配置类上注解@EnableTransactionManagement并在业务类中注解@Transactional。声明式事务通过Spring的AOP机制实现,使用TransactionInterceptor生成AOP代理,在代理中使用PlatformTransactionManager实现类保证事务。
在这里插入图片描述
使用案例:

// the service class that we want to make transactional
// 可以注解在接口、类或public方法上
// 推荐注解在类和public方法上
// 只有外部方法调用能启动事务,类内方法调用不可以
@Transactional(
		propagation = Propagation.REQUIRED,
        isolation = Isolation.READ_COMMITTED,
        // 单位秒
        timeout = 3,
        readOnly = true,
        rollbackFor = {IOException.class,IllegalArgumentException.class},
        noRollbackFor = {AccessException.class}
)
public class DefaultFooService implements FooService {
    public Foo getFoo(String fooName);
    public Foo getFoo(String fooName, String barName);
    public void insertFoo(Foo foo);
    public void updateFoo(Foo foo);
}


public class DefaultBarService implements BarService{
	@Transactional(...)
	public void updateBar(Bar foo);
}

AOP

10. Aspect Oriented Programming with Spring

关于aop方式需要关注,TransactionInterceptor的优先级,比如我们使用自定义aop方式实现分布式锁来包裹一个声明式事务,需要注意aop分布式锁和aop事务的优先级,分布式锁必须包裹住事务。TransactionInterceptor的优先级比较低,通常来说是代理过程的最内层。

Advice ordering

Programmatic transaction management

两种方式实现编程式事务:

  1. Using the TransactionTemplate
  2. Using a PlatformTransactionManager implementation directly.
// 使用TransactionTemplate
public class SimpleService implements Service {

    private final TransactionTemplate transactionTemplate;

    public SimpleService(PlatformTransactionManager transactionManager) {
        Assert.notNull(transactionManager, "The 'transactionManager' argument must not be null.");
        this.transactionTemplate = new TransactionTemplate(transactionManager);

        // the transaction settings can be set here explicitly if so desired
        this.transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_UNCOMMITTED);
        this.transactionTemplate.setTimeout(30); // 30 seconds
        // and so forth...
    }


	public Object transaction() {
        return transactionTemplate.execute(new TransactionCallback() {
            // the code in this method executes in a transactional context
            public Object doInTransaction(TransactionStatus status) {
                updateOperation1();
                return resultOfUpdateOperation2();
            }
        });
    }
	
	public void transactionWithoutResult(){
		transactionTemplate.execute(new TransactionCallbackWithoutResult() {
				protected void doInTransactionWithoutResult(TransactionStatus status) {
        			try {
            			updateOperation1();
            			updateOperation2();
        				} catch (SomeBusinessExeption ex) {
            				status.setRollbackOnly();
        				}
    			}
		});
	}
    ...
}
// 直接使用PlatformTransactionManager
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
// explicitly setting the transaction name is something that can only be done programmatically
def.setName("SomeTxName");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

TransactionStatus status = txManager.getTransaction(def);
try {
    // execute your business logic here
}
catch (MyException ex) {
    txManager.rollback(status);
    throw ex;
}
txManager.commit(status);

编程式事务 or 声明式事务?
Programmatic transaction management is usually a good idea only if you have a small number of transactional operations.
if you have a web application that require transactions only for certain update operations, you may not want to set up transactional proxies using Spring or any other technology.
if your application has numerous transactional operations, declarative transaction management is usually worthwhile. It keeps transaction management out of business logic, and is not difficult to configure.

Transaction bound event

参见Spring 中的事件发布与监听

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值