java积累——数据库手动控制事务工具类

简介: java积累——数据库手动控制事务工具类

引言


在项目中对数据库操作的时候保证事务的完整性是非常重要的,尤其是一个功能中需要对数据库多次操作的时候更是需要小心,其实简单的说:只要保证多次操作使用一个Connection就可以使他们在一个事务中,但是数据库jdbc默认在执行完executeQuery、executeUpdate等方法以后会自动提交事务,这样我们多次操作的时候就不能保证事务的完整性,所以需要我们手动控制事务的提交和回滚操作,下面提供一个帮助类。


package com.bjpowernode.drp.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
 * 
 * @author zhenghao
 *
 */
public class DbUtil {
  public static Connection getConnection(){
    /*Connection conn=null;
    try {
      Class.forName("oracle.jdbc.driver.OracleDriver");
      String url="jdbc:oracle:thin:@127.0.0.1:1521:databaseName";
      String username="userName";
      String password="password";
      try {
        conn=DriverManager.getConnection(url, username, password);
      } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    } catch (ClassNotFoundException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    return conn;*/
    Connection conn=null;
    try {
      JdbcConfig jdbcConfig=XmlConfigReader.getInstance().getJdbcConfig();      
      Class.forName(jdbcConfig.getDriverName());
      try {
        conn=DriverManager.getConnection(jdbcConfig.getUrl(), jdbcConfig.getUserName(), jdbcConfig.getPassword());
      } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    } catch (ClassNotFoundException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    return conn;
  }
  public static void close(Connection conn){
    if (conn!=null) {
      try {
        conn.close();
      } catch (SQLException e) {
        e.printStackTrace();
      }
    }
  }
  public static void close(Statement statement){
    if (statement!=null) {
      try {
        statement.close();
      } catch (SQLException e) {
        e.printStackTrace();
      } 
    }
  }
  public static void close(ResultSet rs) {
    if(rs!=null){
      try {
        rs.close();
      } catch (SQLException e) {
        e.printStackTrace();
      }
    }
  }
  public static void beginTransaction(Connection conn){
    if (conn!=null) {
      try {
        if(conn.getAutoCommit()){
          conn.setAutoCommit(false);
        }
      } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
  }
  public static void commitTransaction(Connection conn){
    try {
      if(conn!=null){
        if (!conn.getAutoCommit()) {
          conn.commit();
        }
      }
    } catch (Exception e) {
      // TODO: handle exception
    }
  }
  public static void rollbackTransaction (Connection conn) {
    try {
      if(conn!=null){
        if (!conn.getAutoCommit()) {
          conn.rollback();
        }
      }
    } catch (Exception e) {
      // TODO: handle exception
    }
  }
  public static void resetTransaction(Connection conn){
    try {
      if(conn!=null){
        if (conn.getAutoCommit()) {
          conn.setAutoCommit(false);
        }else{
          conn.setAutoCommit(true);
        }
      }
    } catch (Exception e) {
      // TODO: handle exception
    }
  }
}

上面的工具类中提供了数据库的连接操作;手动开启事务、提交事务、事务回滚、恢复事务状态;关闭Connection ;关闭Statement;关闭ResultSet等等操作,这样在和数据库打交道的时候会方便很多。


手动控制事务示例演示


当我们添加一个节点以后,需要判断这个节点是不是叶子(是有有子节点)而改变is_leaf这个字段的值;


public void addClientOrRegion(Client clientOrRegion) {
    StringBuffer sbSql = new StringBuffer();
    sbSql.append("insert into t_client ( ")
        .append("id, pid, client_level_id, ")
        .append("name, client_id, bank_acct_no, ")
        .append("contact_tel, address, zip_code, ")
        .append("is_leaf, is_client) ")
        .append("values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ");
    Connection conn = null;
    PreparedStatement pstmt = null;
    try {
      conn = DbUtil.getConnection();
      pstmt = conn.prepareStatement(sbSql.toString());
      <strong><span style="color:#ff0000;">DbUtil.beginTransaction(conn);</span></strong>
      // 根据表明获得id,利用id生成器
      pstmt.setInt(1, IdGenerator.generate("t_client"));
      pstmt.setInt(2, clientOrRegion.getPid());
      pstmt.setString(3, clientOrRegion.getClientLevel().getId());
      pstmt.setString(4, clientOrRegion.getName());
      pstmt.setString(5, clientOrRegion.getClientId());
      pstmt.setString(6, clientOrRegion.getBankAcctNo());
      pstmt.setString(7, clientOrRegion.getContactTel());
      pstmt.setString(8, clientOrRegion.getAddress());
      pstmt.setString(9, clientOrRegion.getZipCode());
      pstmt.setString(10, clientOrRegion.getIsLeaf());
      pstmt.setString(11, clientOrRegion.getIsClient());
      pstmt.executeQuery();
      // 根据id查询分销商或者区域,确定是否为叶子
      Client client = findClientOrRegionById(clientOrRegion.getPid());
      if (Constants.YES.equals(client.getIsLeaf())) {
        // 如果非叶子 应该改为叶子
        modifyIsLeafField(conn, clientOrRegion.getPid(), Constants.NO);
      }
      <strong><span style="color:#ff0000;">DbUtil.commitTransaction(conn);</span></strong>
    } catch (Exception e) {
      // TODO: handle exception
      e.printStackTrace();
      <strong><span style="color:#ff0000;">DbUtil.rollbackTransaction(conn);</span></strong>
    } finally {
      DbUtil.close(pstmt);
      <strong><span style="color:#ff0000;">DbUtil.resetTransaction(conn);</span></strong>
      DbUtil.close(conn);
    }
  }

当我们得到connection以后,调用方法来设置事务的提交为手动提交,这样当我们将两步操作都完成以后自己手动提交,如果遇到错误以后调用方法回滚事务,这样我们就可以事务的完整性。在最后释放资源的时候不要忘记恢复事务的提交状态


小结


事务在数据库中是非常重要的,尤其是项目比较大的时候,如果不能保证事务会给我们带来很大的麻烦有时候甚至是灾难。

目录
相关文章
|
6月前
|
中间件 关系型数据库 Go
Go语言数据库编程:数据迁移与事务控制
本文介绍了《Go语言实战指南》中关于数据库编程的核心内容,涵盖使用 GORM 进行数据迁移与事务控制。主要内容包括:AutoMigrate 方法自动创建或更新表结构;事务控制的自动与手动实现方式;事务隔离级别的设置;以及在 Gin 框架中统一管理事务的实践建议。适合开发阶段的数据库结构管理和事务性操作需求。
|
7月前
|
负载均衡 算法 关系型数据库
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
|
8月前
|
Java 关系型数据库 MySQL
Java汽车租赁系统源码(含数据库脚本)
Java汽车租赁系统源码(含数据库脚本)
184 4
|
8月前
|
NoSQL Java API
在Java环境下如何进行Redis数据库的操作
总的来说,使用Jedis在Java环境下进行Redis数据库的操作,是一种简单而高效的方法。只需要几行代码,就可以实现复杂的数据操作。同时,Jedis的API设计得非常直观,即使是初学者,也可以快速上手。
363 94
|
9月前
|
人工智能 JSON Java
列表结构与树结构转换分析与工具类封装(java版)
本文介绍了将线性列表转换为树形结构的实现方法及工具类封装。核心思路是先获取所有根节点,将其余节点作为子节点,通过递归构建每个根节点的子节点。关键在于节点需包含 `id`、`parentId` 和 `children` 三个属性。文中提供了两种封装方式:一是基于基类 `BaseTree` 的通用工具类,二是使用函数式接口实现更灵活的方式。推荐使用后者,因其避免了继承限制,更具扩展性。代码示例中使用了 Jackson 库进行 JSON 格式化输出,便于结果展示。最后总结指出,理解原理是进一步优化和封装的基础。
296 0
|
9月前
|
SQL 数据库 索引
【YashanDB数据库】大事务回滚导致其他操作无法执行,报错YAS-02016 no free undo blocks
大事务回滚导致其他操作无法执行,报错YAS-02016 no free undo blocks
|
9月前
|
前端开发 JavaScript Java
[Java计算机毕设]基于ssm的OA办公管理系统的设计与实现,附源码+数据库+论文+开题,包安装调试
OA办公管理系统是一款基于Java和SSM框架开发的B/S架构应用,适用于Windows系统。项目包含管理员、项目管理人员和普通用户三种角色,分别负责系统管理、请假审批、图书借阅等日常办公事务。系统使用Vue、HTML、JavaScript、CSS和LayUI构建前端,后端采用SSM框架,数据库为MySQL,共24张表。提供完整演示视频和详细文档截图,支持远程安装调试,确保顺利运行。
396 17
|
10月前
|
存储 缓存 Java
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
1222 3
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
|
10月前
|
人工智能 JavaScript 关系型数据库
【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
389 14
【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
|
2月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
189 1

热门文章

最新文章