• 事务的编程模型


    在上一篇文章里面写了关于事务的一些特性,这里在谈谈事务的编程模型。什么叫做事务的编程模型,这个问题比较难以回答,其实简单的一句话,就是我们如何去使用和控制事务。在java平台里面,有三种事务编程模型:本地事务模型,编程式事务模型,声明式事务模型(当然我不是太认同这种说法,并不是太准确,不过大体也就这么回事情)

    • 本地事务模型

    本地事务模型:不用事务的编程框架来管理事务,直接使用资源管理器来控制事务。典型的就是java.sql.Connection 中的  setAutoCommit、commit、rollback方法,见下面一段代码,直接使用资源管理器进行事务控制

            Connection conn = getConnection();
            conn.setAutoCommit(false);
            // do something
            boolean success = doSomething();
            if (success) {
                conn.commit();
            } else {
                conn.rollback();
            }
        
    • 编程式事务模型

    编程式事务模型:就是使用java提供的事务api JTA(Java Transaction API)

    和事务服务提供者(一般是指j2ee容器) 进行事务控制,JTA里面提供了 java.transaction.UserTransaction ,里面定义了下面几个方法

    begin:开启一个事务

    commit:提交当前事务

    rollback:回滚当前事务

    setRollbackOnly:把当前事务标记为回滚

    setTransactionTimeout:设置事务的事件,超过这个事件,就抛出异常,回滚事务

    getStatus;

    不过JTA只是提供了一个接口,并没有提供具体的实现,而是由j2ee服务器提供商 根据JTS规范提供的。下面一段代码演示了如何使用事务JPA

            InitialContext ctx = new InitialContext();
            UserTransaction ut = (UserTransaction)
        ctx.lookup("javax.transaction.UserTransaction");
            
            ut.begin();
            //do something
            boolean isSuccess = doSomething() ;
            
            if(isSuccess){
                ut.commit();
            }else{
                ut.rollback();
            }

    JPA规范里面定义了事务相关的几个角色:事务上下文,资源管理器,通信管理器,应用程序,事务管理器,事务服务提供者。其中资源管理器主要就是我们常见的数据库连接和JMS连接,事务上下文这里可以理解为事务的状态和属性信息,应用程序就是使用事务服务的程序,事务服务提供者就是实现了jta规范的j2ee容器。事务管理器就是应用程序和事务服务提供者的api接口。通信管理器主要是用在分布式事务里面。

    这个是java里面JPA的规范,但是也有一些编程框架提供了自己的编程事务模型,例如java里最常用的就是spring的事务管理器,下面是spring提供的编程接口:org.springframework.transaction.PlatformTransactionManager,这里面就只有三个方法:

    getTransaction:根据属性信息决定是否开启事务(具体可以看上一篇文章里面的事务特性小结里面的事务传播属性)

    commit;提交当前事务

    rollback;回滚当前事务

    我们发现其实和JPA提供的编程模型很像,就是开启一个事务,提交还是回滚事务。spring提供的事务编程框架也比较简单

    ApplicationContext context = getApplicationContext();
            TransactionTemplate transactionTemplate = (TransactionTemplate)context.getBean("TransactionTemplate");
            
            transactionTemplate.execute(new TransactionCallback() {
                public Object doInTransaction(TransactionStatus status) {
                    boolean isSuccess = doSomething() ;
    
                    if(isSuccess){
                        
                    }else{
                        status.setRollbackOnly();
                    }
                    return isSuccess;
                }    
            });
    • 声明式编程

    声明式编程:这种编程模型不采用硬编码的方式,而是采用在xml里面进行配置的方式或者使用anotation的方式进行。例如srping里面可以通过aop进行实现

    <bean id="accountService"
    class="org.springframework.transaction.interceptor. TransactionProxyFactoryBean">
    <property name="transactionManager" ref="transactionManager"/> 
    <property name="target" ref="accountServiceTarget"/>
    <property name="transactionAttributes">
    <props>
   <prop key="*">PROPAGATION_SUPPORTS</prop>   <prop key="update*">PROPAGATION_REQUIRED </prop> </props> </property>

    以上三种编程模型,第一种比较简单,也只是适合控制单个资源事务,如果涉及到跨资源(比如两个数据库连接之间)事务控制,就无能为力了,也就是说不能够提供分布式事务的解决方案, 而JPA提供了分布式事务的解决方案,这一块以前了解过,后来忘记了,准备在温习一下,在整理和总结以下。而spring提供的编程事务模型,则是在局部事务和JPA事务的基础上提供了一层封装,统一了两者的编程模型,也就是说spring其实也提供JPA的编程接口,也就是 JtaTransactionManager,只不过具体实现 委托给jta provider而已。所以基本上编程模型这个划分还是比较模糊的,直接使用spring提供的编程模型即可。

  • 相关阅读:
    跟vczh看实例学编译原理——二:实现Tinymoe的词法分析
    跟vczh看实例学编译原理——一:Tinymoe的设计哲学
    跟vczh看实例学编译原理——零:序言
    2013年终总结
    如何设计一门语言(十二)——设计可扩展的类型
    开始用Word 2013来写博客
    如何设计一门语言(十一)——删减语言的功能
    如何设计一门语言(十)——正则表达式与领域特定语言(DSL)
    链表
    结构的学习
  • 原文地址:https://www.cnblogs.com/aigongsi/p/2717372.html
Copyright © 2020-2023  润新知