`
palwang
  • 浏览: 50512 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

利用ThreadLocal控制多个dao调用事务

 
阅读更多
/* 获取connection 对象* /
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

import oracle.jdbc.driver.OracleDriver;

/**
* @author sfluo
*
* TODO To change the template for this generated type comment go to Window -
* Preferences - Java - Code Style - Code Templates
*/
public class DBUtil {

public static Connection conn;

public static Connection getConnection() {

  try {

   DriverManager.registerDriver(new OracleDriver());
   conn = DriverManager.getConnection(
     "jdbc:oracle:thin:@10.100.143.161:1521:gb02", "gib", "gib");
  } catch (SQLException e) {
   e.printStackTrace();
  }

  return conn;
}

}

利用ThreadLocal保存connection对象
package conn;

import java.sql.Connection;
import java.sql.SQLException;

/**
* @author sfluo
*
* TODO To change the template for this generated type comment go to Window -
* Preferences - Java - Code Style - Code Templates
*/
public class ConnectionManage {
private static ThreadLocal currentConn = new ThreadLocal();

public static Connection currentConnection() {

  Connection conn = (Connection) currentConn.get();
  if (conn == null) {
   conn = DBUtil.getConnection();
   currentConn.set(conn);
   openTransaction();
  }
  return conn;
}

public static void closeConnection() {
  try {
   Connection conn = (Connection) currentConn.get();
   currentConn.set(null);
   if (conn != null) {
    conn.close();
   }
  } catch (SQLException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

}

public static void openTransaction() {
  try {
   Connection conn = currentConnection();
   conn.setAutoCommit(false);
   conn.setTransactionIsolation(2);
  } catch (SQLException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

}

public static void commit() {
  try {
   Connection conn = currentConnection();
   if (conn != null)
    conn.commit();
  } catch (SQLException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

}

public static void roolback() {
  try {
   Connection conn = currentConnection();
   if (conn != null)
    conn.rollback();
  } catch (SQLException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

}

}

被简化的dao实现
package conn;


import java.sql.PreparedStatement;

/**
* @author sfluo
*
* TODO To change the template for this generated type comment go to Window -
* Preferences - Java - Code Style - Code Templates
*/
public class DaoA {


public static final String sql = "insert into t_user_bnas (id_globalsession,id_dispseq) values('11200409220000001279','1100')";

void createData() throws Exception {
  PreparedStatement pstmt = ConnectionManage.currentConnection().prepareStatement(sql);

  pstmt.execute();

  pstmt.close();

}

}

package conn;

import java.sql.Connection;
import java.sql.PreparedStatement;

/**
* @author sfluo
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class DaoB {
Connection conn;

DaoB() {
  this.conn = ConnectionManage.currentConnection();
}

public static final String sql = "update t_user_bnas set id_1dispseq='1111' where id_globalsession='11200409220000001279'";

void createData() throws Exception {
  PreparedStatement pstmt = conn.prepareStatement(sql);

  pstmt.execute();

  pstmt.close();
 

}
}
测试例子
package conn;

/**
* @author sfluo
*
* TODO To change the template for this generated type comment go to Window -
* Preferences - Java - Code Style - Code Templates
*/
public class Test {

public static void main(String args[]) {
  Test test = new Test();
  test.testMethod();
}

DaoA daoA = new DaoA();

DaoB daoB = new DaoB();

void testMethod() {

  try {

   daoA.createData();
   daoB.createData();
  } catch (Exception e) {

   ConnectionManage.roolback();

  } finally {
   ConnectionManage.closeConnection();

  }
}

}
分享到:
评论

相关推荐

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

    假设我们有一个Service方法,它需要调用多个Dao方法,并且所有Dao操作都在同一个数据库事务中。传统的做法是手动管理数据库连接,如下所示: ```java public void serviceMethod() { Connection conn = null; try...

    ThreadLocal详解

    例如,在Spring的DAO模板类中,尽管底层的数据连接或会话资源是非线程安全的,但是通过使用ThreadLocal,可以为每个线程绑定独立的数据连接或会话,使得多个DAO可以复用同一个模板实例而不会发生资源冲突,极大地...

    dao设计模式DAO 设计模式之事务界定疯.pdf

    当业务逻辑层需要频繁地调用不同的DAO方法时,每个DAO方法都需要独立地开启和提交事务,这不仅增加了代码的复杂性,还可能导致事务管理错误。 为了更好地解决这个问题,可以采用一种更高级的设计方案,即在DAO层...

    DAO多线程的技巧.rar_dao

    - **静态内部类和单例模式**:为了防止多个线程同时访问同一DAO实例,可以采用静态内部类实现单例模式,确保线程安全。静态内部类保证了线程安全的同时,也延迟了单例的初始化。 - **线程局部变量**:使用...

    Hibernate业务层控制Hibernate业务层控制

    然而,在复杂的业务场景下,一个业务流程可能需要调用多个DAO方法,这就会导致事务控制分散且难以管理。例如: ```java // 示例代码 dao1.save(object); dao2.update(object); ``` 如果`dao2.update()`方法抛出...

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

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

    javaWeb实现事务1

    `FilterChain`的`doFilter(request, response)`方法调用使得请求继续在过滤器链中传递,期间可能会有多个DAO操作。由于每个DAO都在同一个线程中运行,因此可以通过`ConnectionContext.getSingleton().get()`获取并...

    JAVA设计模式之事务处理

    这是因为业务服务层通常代表一个完整的业务操作,它可能需要调用多个DAO来完成任务。例如,在一个简单的网上书店购书场景中,`BookStoreManager`服务会涉及到`BookDAO`和`CustomerDAO`的交互,确保库存减少、账户扣...

    详解基于spring多数据源动态调用及其事务处理

    在实际开发中,我们经常需要连接多个数据库,但是,在方法调用前并不知道到底是调用哪个数据库。为了解决这个问题,我们可以使用基于Spring的多数据源动态调用机制。下面我们将详细介绍基于Spring的多数据源动态调用...

    Mybatis多数据源调用

    然而,有时我们需要处理多个不同的数据库,这就涉及到了多数据源的配置和切换。本文将深入探讨如何在MyBatis中实现多数据源调用。 一、多数据源需求与场景 在大型系统中,为了数据安全、性能优化或者业务隔离,往往...

    java开始面试的第23天.doc

    Java面试的第23天,我们来探讨几个关键的Java技术点:JDBC事务控制、批处理、ThreadLocal的工作原理、分页查询及其优化,以及DAO层事务的封装。 1. JDBC事务控制: JDBC提供了对数据库事务的管理,主要通过`...

    32.8、高并发线程1

    线程安全问题通常出现在共享资源的并发环境中,例如,当多个线程同时访问并修改一个全局变量时,可能导致数据的不一致性和并发错误。`ThreadLocal`就是为了解决这类问题而设计的。在给定的例子中,DAO层的数据库连接...

    DBUtils操作数据库以及事物的管理

    - 使用`QueryRunner`对象执行多个SQL语句。 ```java QueryRunner runner = new QueryRunner(); String sql1 = "update account set money=money-100 where id=1"; runner.update(conn, sql1); String sql2 =...

    sping多数据源动态切换

    例如,如果在Service层启用了事务,那么在调用Service方法之前(如在Controller层)就应该完成数据源的切换,避免在Service层及其数据访问层(DAO层)中进行切换。 总的来说,Spring的动态数据源切换提供了一种高效...

    每日作业卷2

    `ThreadLocal`在多线程环境中用于存储每个线程的私有副本,例如在Java应用中,每个线程可以有自己的`Connection`对象,避免了线程间共享导致的并发问题。 **6. 事务的隔离级别** MySQL支持四种事务隔离级别: - **...

    Spring.3.x企业应用开发实战(完整版).part2

    10.4.2 启动独立线程调用事务方法 10.5 联合军种作战的混乱 10.5.1 Spring事务管理器的应对 10.5.2 Hibernate+Spring JDBC混合框架的事务管理 10.6 特殊方法成漏网之鱼 10.6.1 哪些方法不能实施Spring AOP事务 ...

    Spring3.x企业应用开发实战(完整版) part1

    10.4.2 启动独立线程调用事务方法 10.5 联合军种作战的混乱 10.5.1 Spring事务管理器的应对 10.5.2 Hibernate+Spring JDBC混合框架的事务管理 10.6 特殊方法成漏网之鱼 10.6.1 哪些方法不能实施Spring AOP事务 ...

    SpringBoot多数据源动态切换源码

    在多数据源环境中,应用需要连接并操作多个不同的数据库。在Spring Boot中,可以通过配置不同的DataSource bean来实现。每个数据源可以配置独立的URL、用户名和密码,以满足不同业务的需求。 4. **动态数据源切换*...

    基于Spring+Ibatis的安全线程实现

    然而,如果这些服务类中包含对数据库的操作,如Ibatis的SqlSession,那么必须注意线程隔离,防止多个线程共享同一SqlSession实例,导致数据错乱。因为SqlSession不是线程安全的,每个线程都应该有自己独立的...

    Spring中文帮助文档

    9.9.1. 对一个特定的 DataSource 使用了错误的事务管理器 9.10. 更多的资源 10. DAO支持 10.1. 简介 10.2. 一致的异常层次 10.3. 一致的DAO支持抽象类 11. 使用JDBC进行数据访问 11.1. 简介 11.1.1. 选择一...

Global site tag (gtag.js) - Google Analytics