java简单实现事务控制的demo

简介: java简单实现事务控制的demo

1.实现事务控制的基本思路



1.1代理机制


最原始的做法就是在每个数据库操作的时候通过用一个链接传递实现对事务的控制。
这样的话重复代码太多,不容易控制事务。
如果用代理机制的话就可以很方便的解决这个问题。
代理的是什么?
事务统一的开启,提交,回滚,释放
复制代码


1.2事务的获取要保证当前的线程处理是唯一的


这里用到了Java的ThreadLocal会保证当前的线程只有一个链接再用
复制代码


2.实现过程



2.1数据库链接工具类


public class JDBCUtil {
  private JDBCUtil() {
  }
  private static ThreadLocal<Connection> threadConn = new ThreadLocal<Connection>();
  // 获取数据库连接
  public static Connection getConnection() {
    Connection conn = threadConn.get();
    if (conn == null) {
      try {
        System.out.println("创建链接");
        Class.forName("oracle.jdbc.driver.OracleDriver");//找到oracle驱动器所在的类
        String url="jdbc:oracle:thin:@127.0.0.1:1521:orcl"; //URL地址
        String username="test";
        String password="test";
        conn=DriverManager.getConnection(url, username, password);
      } catch (ClassNotFoundException e) {
        e.printStackTrace();
      } catch (SQLException e) {
        e.printStackTrace();
      }
      threadConn.set(conn);
    }
    return conn;
  }
  // 设置事务手动提交
  public static void benigTransction(Connection conn) {
    System.out.println("事务手动提交");
    try {
      if (conn != null) {
        if (conn.getAutoCommit()) {
          conn.setAutoCommit(false);
        }
      }
    } catch (SQLException e) {
      e.printStackTrace();
    }
  }
  // 提交事务
  public static void endTransction(Connection conn) {
    System.out.println("提交事务");
    try {
      if (conn != null) {
        if (!conn.getAutoCommit()) {
          conn.commit();
        }
      }
    } catch (SQLException e) {
      e.printStackTrace();
    }
  }
  // 设置Connection的原始状态
  public static void recoverTransction(Connection conn) {
    System.out.println("恢复设置");
    try {
      if (conn != null) {
        if (conn.getAutoCommit()) {
          conn.setAutoCommit(false);
        } else {
          conn.setAutoCommit(true);
        }
      }
    } catch (SQLException e) {
      e.printStackTrace();
    }
  }
  // 发生异常回滚事务
  public static void rollback(Connection conn) {
    System.out.println("回滚设置");
    try {
      if (conn != null) {
        conn.rollback();
      }
    } catch (SQLException e) {
      e.printStackTrace();
    }
  }
  // 关闭连接,并将其从当前线程删除
  public static void close() {
    System.out.println("关闭删除");
    Connection conn = threadConn.get();
    if (conn != null) {
      try {
        conn.close();
        conn = null;
        threadConn.remove();
      } catch (SQLException e) {
        e.printStackTrace();
      }
    }
  }
}
复制代码


2.2数据库事务控制的动态代理类


public class DaoProxy implements MethodInterceptor {
  public Object intercept(Object object, Method method, Object[] objects, MethodProxy proxy) throws Throwable {
    // 用于接收参数
    // 如果是以下方法开头,则代理事务
    Object result=null;
    if (method.getName().startsWith("add") ||
      method.getName().startsWith("del")||
      method.getName().startsWith("update")) {
      Connection conn = JDBCUtil.getConnection();
      try {
        // 手动提交事务
        JDBCUtil.benigTransction(conn);
        result=proxy.invokeSuper(object, objects);
        // 提交事务
        JDBCUtil.endTransction(conn);
      } catch (Exception e) {
        e.printStackTrace();
        // 回滚事务
        JDBCUtil.rollback(conn);
      } finally {
        // 还原状态
        JDBCUtil.recoverTransction(conn);
        JDBCUtil.close();
      }
    }else {
      result=proxy.invokeSuper(object, objects);
    }
    return result;
  }
}
复制代码


2.3对sql提交的基类


public class BaseDao {
  public int insert(String sql,List<Object> values) throws SQLException {
    Connection con=JDBCUtil.getConnection();
    PreparedStatement pre=con.prepareStatement(sql);
    for(int index=0;index<values.size();index++) {
       Object obj=values.get(index);
       if(obj.getClass().isInstance(Integer.class)) {
         pre.setInt(index+1, (Integer)obj);
       }else if(obj.getClass().isInstance(Double.class)) {
         pre.setDouble(index+1, (Double)obj);
       }else if(obj.getClass().isInstance(BigDecimal.class)) {
         pre.setBigDecimal(index+1, (BigDecimal)obj);
       }else if(obj.getClass().isInstance(java.sql.Date.class)) {
         pre.setDate(index+1, (java.sql.Date)obj);
       }else if(obj.getClass().isInstance(java.util.Date.class)) {
         pre.setDate(index+1, new java.sql.Date(((java.util.Date)obj).getTime()));
       }else {
         pre.setString(index+1, obj.toString());
       }
    }
    return pre.executeUpdate();
  }
}
复制代码


2.4数据添加的测试DAO


public class DAOTest extends BaseDao{
  public void addTest(String test) throws SQLException {
    String id=UUID.randomUUID().toString().replace("-", "");
    String addSql="insert into TEST (ID,TEST) values (?,?)";
    List<Object> values=new ArrayList<Object>();
    values.add(id);
    values.add(test);
        this.insert(addSql, values);
  }
  public void addTestError(String test) throws SQLException {
    String id=UUID.randomUUID().toString().replace("-", "");
    String addSql="insert into TEST (ID,TEST) values (?,?)";
    List<Object> values=new ArrayList<Object>();
    values.add(id);
    values.add(test);
        this.insert(addSql, values);
        throw new SQLException("回滚测试");
  }
}
复制代码


2.4效果


public class TestDao {
  public static void main(String[] args) throws SQLException {
    DaoProxy daoProxy = new DaoProxy();
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(DAOTest.class);
    enhancer.setCallback(daoProxy);
    DAOTest dt=(DAOTest)enhancer.create();
    dt.addTest("123");
    dt.addTestError("456");
  }
}
复制代码


网络异常,图片无法展示
|


网络异常,图片无法展示
|

相关文章
|
4月前
|
Java Spring
Java事务&事务失效场景
Java事务&事务失效场景
65 0
|
2月前
|
设计模式 Java
26、Java 简单实现单例设计模式(饿汉式和懒汉式)
26、Java 简单实现单例设计模式(饿汉式和懒汉式)
30 2
|
6月前
|
Java
java判断Object对象是否为空demo
java判断Object对象是否为空demo
|
6月前
|
Java
Java实现计算器demo
Java实现计算器demo
|
9月前
|
SQL Java 数据库
第一季:8spring支持的常用数据库事务传播属性和事务隔离级别【Java面试题】
第一季:8spring支持的常用数据库事务传播属性和事务隔离级别【Java面试题】
99 0
|
8月前
|
Java API
Java调用淘宝API demo源代码
Java调用淘宝API demo源代码
72 0
|
6天前
|
Java 数据库连接 数据库
16:事务-Java Spring
16:事务-Java Spring
25 5
|
26天前
|
JavaScript Java 测试技术
基于Java的班级事务管理系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的班级事务管理系统的设计与实现(源码+lw+部署文档+讲解等)
23 1
|
28天前
|
JavaScript Java 测试技术
基于Java的校园事务自助指南服务系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的校园事务自助指南服务系统的设计与实现(源码+lw+部署文档+讲解等)
19 0
|
2月前
|
XML Java 数据库
java如何设置事务超时时间
【2月更文挑战第16天】