`
jiakechong
  • 浏览: 212024 次
社区版块
存档分类
最新评论

ThreadLocal封装Connection--事务统一管理

 
阅读更多
ThreadLocal封装Connection--事务统一管理

ThreadLocal:线程本地变量该类提供了线程局部变量。这些变量不同于它们的普通对应物,因为访问一个变量(通过其 get 或 set 方法)的每个线程都有自己的局部变量,它独立于变量的初始化副本。ThreadLocal 实例通常是类中的私有静态字段,它们希望将状态与某一个线程(例如,用户 ID 或事务 ID)相关联。

        事务是一种机制、是一种操作序列,它包含了一组数据库操作命令,这组命令要么全部执行,要么全部不执行。因此事务是一个不可分割的工作逻辑单元。在数据库系统上执行并发操作时事务是作为最小的控制单元来使用的。这特别适用于多用户同时操作的数据通信系统。

       在业务逻辑中我们要统一管理事务,但是在一个事务中会涉及到多个Dao,不同的DAO取得的是不同的Connection对象,这样就不能实现统一管理事务。

       那么怎么才能实现两个或多个DAO用同一个事务来控制,来统一管理事务那?

        首先就要解决一个根本问题,我们在一个事务中,不同的DAO取得的是同一个Connection,这个要怎么实现呢。我们想到了TheadLocal.

        因为当一个业务逻辑要对多个DAO进行处理的时候,此操作属于同一个线程内。所以,我们希望能把此Connection放在线程内,或者和线程有关联。

       在任何一个线程内都可以用ThreadLocal来保存一个变量的copy,这样,如果此对象存在,就可以直接取用。

        如果ThreadLocal中放置connection, 保证事务中的DAO类获取的都是同一个connection,这样才保证事务。所以,在同一个线程内,不同的DAO就可以保证取得到的是同一个Connection

       这样就实现了,事务的统一管理

      ThreadLocal的API如下图:



   下面是ThreadLocal对Connection的封装

/*
*采用ThreadLocal封装Connection
*
*/ 
public Class ConnectionManager { 
     
    //创建一个私有静态的并且是与事务相关联的局部线程变量 
    private static ThreadLocal<Connection> connectionHolder = new ThreadLocal<Connection>; 
     
    public static Connection getConnection(){ 
        //获得线程变量connectionHolder的值conn 
        Connection conn = connectionHolder.get(); 
        if (conn == null){ 
              //如果连接为空,则创建连接,另一个工具类,创建连接 
                conn = DbUtil.getConnection(); 
                //将局部变量connectionHolder的值设置为conn 
                connectionHolder.set(conn); 
        }    
        return conn; 
    }

/**
* 关闭连接和从线程变量中删除conn
*/ 
public static void closeConnection(){ 
    //获得线程变量connectionHolder的值conn 
    Connection conn = connectionHolder.get(); 
    if (conn != null){ 
        try { 
            //关闭连接 
            conn.close(); 
            //从线程局部变量中移除conn,如果没有移除掉,下次还会用这个已经关闭的连接,就会出错 
            connectionHolder.remove(); 
        }catch(SQLException e){ 
            e.printStackTrace(); 
        } 
    } 


/**
*开启事务,手动开启
*/ 
public static void beginTransaction(Connection conn){ 
        try { 
            //如果连接存在,再设置连接,否则会出错 
            if (conn != null){ 
                    //默认conn是自动提交, 
                    if (conn.getAutoCommit()){ 
                        //关闭自动提交,即是手动开启事务 
                        conn.setAutoCommit(false); 
                    } 
                } 
        }catch(SQLException e){ 
            e.printStackPrince(); 
        } 


/**
* 提交事务
*/ 
public static void commitTransaction(Connection conn){ 
    try{ 
        if (conn != null){ 
            if (!conn.getAutoCommit()){ 
                conn.commit(); 
            } 
        } 
    }catch(SQLException e){ 
        e.printStackTrace(); 
    } 



  /**
     * 回滚事务
     */ 
    public static void rollbackTransaction(){ 
        try { 
            if (conn != null){ 
                if(!conn.getAutoCommit()){ 
                    conn.rollback(); 
                } 
            }    
        }catch(SQLException e){ 
            e.printStackTrace(); 
        }    
    } 
     


//调用业务逻辑事务管理 
public void addFlowCard(FlowCard flowCard) 
        Connection conn = null; 
        try { 
            //从ThreadLocal中取得Connection 
            conn = ConnectionManager.getConnection(); 
             
                //手动控制事务提交 
                ConnectionManager.beginTransaction(conn); 
                 
            //添加流向单主信息 
            flowCardDao.addFlowCardMaster(flowCardVouNo, flowCard); 
             
            //添加流向单明细信息 
            flowCardDao.addFlowCardDetail(flowCardVouNo, flowCard.getFlowCardDetailList()); 
             
            if (!conn.getAutoCommit()) { 
                //提交事务 
                ConnectionManager.commitTransaction(conn); 
            } 
        }catch(Exception e) { 
            e.printStackTrace(); 
            if (!conn.getAutoCommit()) { 
                //回滚事务 
                ConnectionManager.rollbackTransaction(conn); 
            } 
            throw new ApplicationException("操作失败!"); 
        }finally { 
            ConnectionManager.closeConnection(); 
        } 
    } 

分享到:
评论

相关推荐

    事务的封装和Threadlocal实例

    总的来说,结合JDBC的事务管理和ThreadLocal,我们可以在多线程环境中更好地实现数据库操作,确保数据的一致性,并提高代码的可复用性和安全性。通过使用ThreadLocal,我们可以创建线程安全的变量,使得每个线程都能...

    Spring事务处理-ThreadLocal的使用

    在Spring事务管理中,ThreadLocal被用来存储当前线程的事务信息,例如事务隔离级别、是否回滚等。这样,Spring可以在事务范围内正确地传播事务,即使在多线程环境下也能保证事务的正确性。 在Spring的`...

    java事务 - threadlocal

    当Java事务与ThreadLocal结合使用时,可以在不同的线程中维护各自的事务状态,比如在Spring框架中,每个线程的ThreadLocal可以存储一个TransactionStatus对象,这样就可以在线程内部管理当前事务的状态,而不会影响...

    从ThreadLocal的使用到Spring的事务管理

    本文将深入探讨ThreadLocal的使用以及Spring框架中的事务管理,这两个主题都是Java开发人员必须掌握的关键技能。 首先,让我们了解ThreadLocal。ThreadLocal是Java提供的一种线程绑定变量的工具类,它允许我们在一...

    ThreadLocal和事务

    在Java编程领域,ThreadLocal和事务管理是两个关键的概念,特别是在构建复杂且高效的Web应用程序时。ThreadLocal是一种线程局部变量,而事务则是数据库操作的原子性保证。在这个小型简单练习中,我们看到如何结合c3p...

    javaweb 通过threadlocal 手动提交事务

    Spring框架也支持使用ThreadLocal进行事务管理,比如使用`TransactionSynchronizationManager`类,它可以管理和协调事务同步,提供更高级别的事务控制。 通过上述方式,开发者可以利用ThreadLocal在Java Web环境中...

    ThreadLocal

    ThreadLocal是Java编程语言中的一个类,用于在多线程环境中提供线程局部变量。它是一种特殊类型的变量,每个线程都有自己的副本,互不影响,从而实现线程间数据隔离。ThreadLocal通常被用来解决线程共享数据时可能...

    04、导致JVM内存泄露的ThreadLocal详解-ev

    04、导致JVM内存泄露的ThreadLocal详解_ev04、导致JVM内存泄露的ThreadLocal详解_ev04、导致JVM内存泄露的ThreadLocal详解_ev04、导致JVM内存泄露的ThreadLocal详解_ev04、导致JVM内存泄露的ThreadLocal详解_ev04、...

    使用ThreadLocal管理“session”数据

    在Web应用中,特别是对于"session"数据的管理,ThreadLocal可以作为一种有效的解决方案。 1. **什么是Session?** Session是HTTP协议中的一个概念,用于存储用户在服务器端的状态信息。当用户登录网站后,服务器会...

    Spring基于ThreadLocal的“资源-事务”线程绑定设计的缘起

    题目起的有些拗口了,简单说,这篇文章想要解释Spring为什么会选择使用ThreadLocal将资源和事务绑定到线程上,这背后有着什么样的起因和设计动机,通过分析帮助大家更清晰地认识Spring的线程绑定机制。访问任何带有...

    19-事务-源代码.rar

    完成转账。 一、事务概述 二、JDBC事务操作 三、DBUtils事务操作 四、使用ThreadLocal绑定连接资源 五、事务的特性和隔离级别(概念性...执行sql的connection与开启事务的connnection必须是同一个才能对事务进行控制

    myMvcWeb2.rar Java实现

    MVC框架,加注解,Struts框架的思想,动态代理,线程管理对象ThreadLocal,Connection对象池,Properties文件读取,EL表达式,JSTL,JavaBean,Java访问MySQL数据库,增删改查... ---------------------------------...

    ThreadLocal应用示例及理解

    以上就是关于ThreadLocal的基本概念、使用方法、生命周期管理和实际应用示例的详细解释。了解并熟练掌握ThreadLocal可以帮助我们编写出更高效、更安全的多线程代码。在Java并发编程中,ThreadLocal是一个不可或缺的...

    ThreadLocal.pdf

    在实际应用中,ThreadLocal常常与Spring框架中的事务管理一起使用,保证每个线程在事务处理过程中拥有自己独立的资源副本,而不相互干扰。 以上就是ThreadLocal的核心知识点总结。由于原始文本中的部分信息无法准确...

    Quartz-ThreadLocal.rar

    它提供了丰富的 API 和灵活性,使得开发者可以方便地创建、管理和执行定时任务。ThreadLocal 是 Java 中的一个重要工具类,用于在多线程环境中为每个线程维护独立的变量副本。这个压缩包 "Quartz-ThreadLocal.rar" ...

    正确理解ThreadLocal.pdf

    2. **事务处理**:在事务管理中,`ThreadLocal`可以用于维护每个线程的事务状态,确保事务的完整性和一致性。 3. **日志记录**:在多线程环境中,`ThreadLocal`可以用于维护每个线程的日志上下文,如线程ID、用户名...

    ThreadLocal原理及在多层架构中的应用

    - **线程安全的配置对象**:在多层架构中,如Spring框架中,可以使用ThreadLocal来存储线程相关的配置信息,如数据库连接、事务管理等,确保这些对象不会被其他线程访问。 - **HTTP请求上下文**:在Web应用中,可以...

    Synchronized与ThreadLocal

    ### Synchronized与ThreadLocal #### 一、Synchronized机制详解 **Synchronized** 是 Java 中一个非常重要的关键字,主要用于实现线程同步。它通过在对象上加锁来确保多个线程能够安全地访问共享资源。 - **作用...

    通向架构师的道路(第七天)之漫谈使用ThreadLocal改进你的层次的划分.docx

    ThreadLocal 的应用场景非常广泛,例如,在同一服务方法中调用多个 Dao 方法时,可以使用 ThreadLocal 来维护 Connection 对象,达到事务的目的。 例如,在服务层的代码中,可以使用 ThreadLocal 来维护 ...

Global site tag (gtag.js) - Google Analytics