详解Java的JDBC API中事务的提交和回滚

 更新时间:2015年12月28日 08:54:43   投稿:goldensun  
这篇文章主要介绍了Java的JDBC API中事务的提交和回滚,JDBC是Java用于和数据库软件连接的API,需要的朋友可以参考下

如果JDBC连接是在自动提交模式下,它在默认情况下,那么每个SQL语句都是在其完成时提交到数据库。

这可能是对简单的应用程序,但有三个原因,你可能想关闭自动提交和管理自己的事务:

  1. 为了提高性能
  2. 为了保持业务流程的完整性
  3. 使用分布式事务

若要控制事务,以及何时更改应用到数据库。它把单个SQL语句或一组SQL语句作为一个逻辑单元,而且如果任何语句失败,整个事务失败。

若要启用,而不是JDBC驱动程序默认使用auto-commit模式手动事务支持,使用Connection对象的的setAutoCommit()方法。如果传递一个布尔值false到setAutoCommit(),关闭自动提交。可以传递一个布尔值true将其重新打开。

例如,如果有一个名为conn Connection对象,以下代码来关闭自动提交:

conn.setAutoCommit(false);

提交和回滚
一旦已经完成了变化,要提交更改,然后调用commit(在连接对象)方法,如下所示:

conn.commit( );

否则回滚更新对数据库所做的使用命名连接conn,使用下面的代码:

conn.rollback( );

下面的例子演示了如何使用一个提交和回滚对象:

try{
  //Assume a valid connection object conn
  conn.setAutoCommit(false);
  Statement stmt = conn.createStatement();
  
  String SQL = "INSERT INTO Employees " +
        "VALUES (106, 20, 'Rita', 'Tez')";
  stmt.executeUpdate(SQL); 
  //Submit a malformed SQL statement that breaks
  String SQL = "INSERTED IN Employees " +
        "VALUES (107, 22, 'Sita', 'Singh')";
  stmt.executeUpdate(SQL);
  // If there is no error.
  conn.commit();
}catch(SQLException se){
  // If there is any error.
  conn.rollback();
}

在这种情况下没有上述INSERT语句会成功,一切都将被回滚。

事务提交和回滚示例
以下是使用事务提交和回滚描述的例子。

基于对环境和数据库安装在前面的章节中做此示例代码已学习过。

复制过去下面的例子中JDBCExample.java,编译并运行,如下所示:

//STEP 1. Import required packages
import java.sql.*;

public class JDBCExample {
  // JDBC driver name and database URL
  static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; 
  static final String DB_URL = "jdbc:mysql://localhost/EMP";

  // Database credentials
  static final String USER = "username";
  static final String PASS = "password";
  
 public static void main(String[] args) {
  Connection conn = null;
  Statement stmt = null;
  try{
   //STEP 2: Register JDBC driver
   Class.forName("com.mysql.jdbc.Driver");

   //STEP 3: Open a connection
   System.out.println("Connecting to database...");
   conn = DriverManager.getConnection(DB_URL,USER,PASS);

   //STEP 4: Set auto commit as false.
   conn.setAutoCommit(false);

   //STEP 5: Execute a query to create statment with
   // required arguments for RS example.
   System.out.println("Creating statement...");
   stmt = conn.createStatement(
              ResultSet.TYPE_SCROLL_INSENSITIVE,
              ResultSet.CONCUR_UPDATABLE);
   
   //STEP 6: INSERT a row into Employees table
   System.out.println("Inserting one row....");
   String SQL = "INSERT INTO Employees " +
          "VALUES (106, 20, 'Rita', 'Tez')";
   stmt.executeUpdate(SQL); 

   //STEP 7: INSERT one more row into Employees table
   SQL = "INSERT INTO Employees " +
          "VALUES (107, 22, 'Sita', 'Singh')";
   stmt.executeUpdate(SQL);

   //STEP 8: Commit data here.
   System.out.println("Commiting data here....");
   conn.commit();
  
  //STEP 9: Now list all the available records.
   String sql = "SELECT id, first, last, age FROM Employees";
   ResultSet rs = stmt.executeQuery(sql);
   System.out.println("List result set for reference....");
   printRs(rs);

   //STEP 10: Clean-up environment
   rs.close();
   stmt.close();
   conn.close();
  }catch(SQLException se){
   //Handle errors for JDBC
   se.printStackTrace();
   // If there is an error then rollback the changes.
   System.out.println("Rolling back data here....");
  try{
  if(conn!=null)
      conn.rollback();
   }catch(SQLException se2){
     se2.printStackTrace();
   }//end try

  }catch(Exception e){
   //Handle errors for Class.forName
   e.printStackTrace();
  }finally{
   //finally block used to close resources
   try{
     if(stmt!=null)
      stmt.close();
   }catch(SQLException se2){
   }// nothing we can do
   try{
     if(conn!=null)
      conn.close();
   }catch(SQLException se){
     se.printStackTrace();
   }//end finally try
  }//end try
  System.out.println("Goodbye!");
}//end main

  public static void printRs(ResultSet rs) throws SQLException{
   //Ensure we start with first row
   rs.beforeFirst();
   while(rs.next()){
     //Retrieve by column name
     int id = rs.getInt("id");
     int age = rs.getInt("age");
     String first = rs.getString("first");
     String last = rs.getString("last");

     //Display values
     System.out.print("ID: " + id);
     System.out.print(", Age: " + age);
     System.out.print(", First: " + first);
     System.out.println(", Last: " + last);
   }
   System.out.println();
  }//end printRs()
}//end JDBCExample

现在让我们来编译上面的例子如下:

C:>javac JDBCExample.java

当运行JDBCExample,它会产生以下结果:

C:>java JDBCExample
Connecting to database...
Creating statement...
Inserting one row....
Commiting data here....
List result set for reference....
ID: 100, Age: 18, First: Zara, Last: Ali
ID: 101, Age: 25, First: Mahnaz, Last: Fatma
ID: 102, Age: 30, First: Zaid, Last: Khan
ID: 103, Age: 28, First: Sumit, Last: Mittal
ID: 106, Age: 20, First: Rita, Last: Tez
ID: 107, Age: 22, First: Sita, Last: Singh
Goodbye!

相关文章

  • SpringBoot2.0 整合 Dubbo框架实现RPC服务远程调用方法

    SpringBoot2.0 整合 Dubbo框架实现RPC服务远程调用方法

    这篇文章主要介绍了SpringBoot2.0 整合 Dubbo框架 实现RPC服务远程调用 ,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-07-07
  • 一文教你利用Stream API批量Mock数据的方法

    一文教你利用Stream API批量Mock数据的方法

    在日常开发的过程中我们经常会遇到需要mock一些数据的场景,比如说 mock 一些接口的返回或者说 mock 一些测试消息用于队列生产者发送消息。本文将教你如何通过 Stream API 批量 Mock 数据,需要的可以参考一下
    2022-09-09
  • SpringBoot解决循环调用问题

    SpringBoot解决循环调用问题

    作者在将SpringBoot从1.5版本升级至2.6版本,并迁移至阿里云上运行后,遇到了循环调用问题,在Jetty容器中运行没问题,但在Tomcat容器中就出现了循环引用问题,原因是SpringBoot 2.6不鼓励循环引用,暴露出该问题,作者提供了两种解决思路
    2024-10-10
  • springboot 返回json格式数据时间格式配置方式

    springboot 返回json格式数据时间格式配置方式

    这篇文章主要介绍了springboot 返回json格式数据时间格式配置方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • SpringBoot Admin集成诊断利器Arthas示例实现

    SpringBoot Admin集成诊断利器Arthas示例实现

    这篇文章主要为大家介绍了SpringBoot Admin集成诊断利器Arthas示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • Java中的IO流原理和流的分类详解

    Java中的IO流原理和流的分类详解

    这篇文章主要介绍了Java中的IO流原理和流的分类详解,Java io流是Java编程语言中用于输入和输出操作的一种机制。它提供了一组类和接口,用于处理不同类型的数据流,包括文件、网络连接、内存等,需要的朋友可以参考下
    2023-10-10
  • 详解java中的byte类型

    详解java中的byte类型

    Java也提供了一个byte数据类型,并且是基本类型。java byte是做为最小的数字来处理的,因此它的值域被定义为-128~127,也就是signed byte。下面这篇文章主要给大家介绍了关于java中byte类型的相关资料,需要的朋友可以参考下。
    2017-02-02
  • java使用DelayQueue实现延时任务

    java使用DelayQueue实现延时任务

    项目中经常会用到类似一些需要延迟执行的功能,比如缓存,java提供了DelayQueue来很轻松的实现这种功能,下面小编就来和大家介绍一下如何使用DelayQueue实现延时任务吧
    2023-10-10
  • Android仿微信实现左滑显示删除按钮功能

    Android仿微信实现左滑显示删除按钮功能

    这篇文章主要为大家详细介绍了java仿微信实现左滑显示删除按钮功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-10-10
  • 如何使用Spring integration在Springboot中集成Mqtt详解

    如何使用Spring integration在Springboot中集成Mqtt详解

    MQTT是多个客户端通过一个中央服务器传递信息的多对多协议,能高效地将信息分发给一个或多个订阅者,下面这篇文章主要给大家介绍了关于如何使用Spring integration在Springboot中集成Mqtt的相关资料,需要的朋友可以参考下
    2023-02-02

最新评论