JDBC的事务
以下内容引用自http://wiki.jikexueyuan.com/project/jdbc/transactions.html:
如果JDBC连接是处于自动提交模式下,该模式为默认模式,那么每句SQL语句都是在其完成时提交到数据库。
对简单的应用程序来说这种模式相当好,但有三个原因可能想关闭自动提交模式,并管理自己的事务
- 为了提高性能
- 为了保持业务流程的完整性
- 使用分布式事务
可以通过事务在任意时间来控制以及更改应用到数据库。它把单个SQL语句或一组SQL语句作为一个逻辑单元,如果其中任一语句失败,则整个事务失败。
若要启用手动事务模式来代替JDBC驱动程序默认使用的自动提交模式的话,使用Connection对象的的setAutoCommit()方法。如果传递一个布尔值false到setAutoCommit()方法,就关闭自动提交模式。也可以传递一个布尔值true将其再次打开。
例如,如果有一个名为conn的Connection对象,以下的代码将关闭自动提交模式:
conn.setAutoCommit(false);
一、提交和回滚
当完成了修改,并且要提交修改,可以在connection对象里调用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语句不会成功,一切都将被回滚到最初状态。
示例:
//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/Test?serverTimezone=UTC"; // Database credentials
static final String USER = "root";
static final String PASS = "root"; 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
这将产出如下所示的结果:
第二次运行时错误进行回滚:
二、使用还原点
新的JDBC 3.0还原点接口提供了额外的事务控制。大部分现代的数据库管理系统的环境都支持设定还原点,例如Oracle的PL/SQL。
当在事务中设置一个还原点来定义一个逻辑回滚点。如果在一个还原点之后发生错误,那么可以使用rollback方法来撤消所有的修改或在该还原点之后所做的修改。
Connection对象有两个新的方法来管理还原点:
setSavepoint(String savepointName):定义了一个新的还原点。它也返回一个Savepoint对象。
- releaseSavepoint(Savepoint savepointName):删除一个还原点。请注意,它需要一个作为参数的Savepoint对象。这个对象通常是由setSavepoint()方法生成的一个还原点。
有一个rollback (String savepointName)方法,该方法可以回滚到指定的还原点。
下面的例子说明了如何使用Savepoint对象:
try{
//Assume a valid connection object conn
conn.setAutoCommit(false);
Statement stmt = conn.createStatement(); //set a Savepoint
Savepoint savepoint1 = conn.setSavepoint("Savepoint1");
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', 'Tez')";
stmt.executeUpdate(SQL);
// If there is no error, commit the changes.
conn.commit(); }catch(SQLException se){
// If there is any error.
conn.rollback(savepoint1);
}
在这种情况下,之前的 INSERT 语句不会成功,一切都将被回滚到最初状态。
示例:
//STEP 1. Import required packages
import java.sql.*; public class JDBCExample2 {
// JDBC driver name and database URL
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://localhost/Test?serverTimezone=UTC"; // Database credentials
static final String USER = "root";
static final String PASS = "root"; 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 delete statment with
// required arguments for RS example.
System.out.println("Creating statement...");
stmt = conn.createStatement(); // STEP 6: 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 7: delete rows having ID grater than 104
// But save point before doing so.
Savepoint savepoint1 = conn.setSavepoint("ROWS_DELETED_1");
System.out.println("Deleting row....");
String SQL = "DELETE FROM Employees " + "WHERE ID = 100";
stmt.executeUpdate(SQL);
// oops... we deleted too wrong employees!
// STEP 8: Rollback the changes afetr save point 2.
conn.rollback(savepoint1); // STEP 9: delete rows having ID grater than 104
// But save point before doing so.
Savepoint savepoint2 = conn.setSavepoint("ROWS_DELETED_2");
System.out.println("Deleting row....");
SQL = "DELETE FROM Employees " + "WHERE ID = 101";
stmt.executeUpdate(SQL); // STEP 10: Now list all the available records.
sql = "SELECT id, first, last, age FROM Employees";
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
注意:有了Savepoint对象之后可以不用commit方法进行提交。
这将产生如下所示结果:
测试工程:https://github.com/easonjim/5_java_example/tree/master/jdbcbasics/test5
JDBC的事务的更多相关文章
- Spring总结——AOP、JDBC和事务的总结
1.上一次总结了 Spring 的核心三大组件(Core,Beans,Context),今天总结的 AOP.JDBC和事务都可以看成是核心三大组件的应用. 其中 Spring 的事务管理又以 AOP ...
- 【JDBC】事务的使用
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/5868750.html 关于事务的理论知识.ACID特性等等,网上太多了,在此不一一重复.本文主要着重 事务 ...
- MySql事务及JDBC对事务的使用
一 .事务的几个重要特性 1. 原子性 事务内的每个内容不可分割,是一个统一的整体.或同时进行或同时消亡. 2.一致性 事务执行前和事务执行后,状态都是统一的.如A转B 100元,A和B数据总额度没有 ...
- JDBC 之 事务
1.概念:事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部不成功. 2.数据库开启事务的命令dtl: Start transaction开启事务 Rollback回滚事务(撤销) ...
- JDBC之事务隔离级别以及ACID特性
JDBC之事务隔离级别以及ACID特性 事务隔离级别: 1.更新遗失(Lost update) 两个事务都同时更新一行数据,但是第二个事务却中途失败退出,导致对数据的两个修改都失效了.这是因为系统没有 ...
- 事务之使用JDBC进行事务的操作2
本篇将讲诉如何使用JDBC进行数据库有关事务的操作.在上一篇博客中已经介绍了事务的概念,和在MySQL命令行窗口进行开启事务,提交事务以及回滚事务的操作. 似乎事务和批处理都可以一次同时执行多条SQL ...
- JDBC控制事务
概念 事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit).事务通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户程序的执行所引起,并 ...
- JDBC进行事务管理
JDBC进行事务管理 事务的四个特征:原子性 : 是指事务中包含的操作都被看做是一个逻辑单元一致性: 开始前和结束后数据库都处于一致性状态隔离性: 对数据库修改的多个事务是彼此隔离的持久性 事务完成之 ...
- JDBC处理事务
一.什么是事务? 在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务! 二.事务是必须满足4个条件(AC ...
- Java -- JDBC 事务处理, 事务的隔离级别 脏读 不可重复读 等...
1. 事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部不成功. 数据库开启事务命令 •start transaction 开启事务 •Rollback 回滚事务 •Commit ...
随机推荐
- apache设置无缓存
打开httpd.conf 开启扩展 确保开启 LoadModule headers_module modules/mod_headers.so 添加配置项 并添加以下配置,跟据文件类型来让浏览器每次都 ...
- WindowsService+Quartz.NET快速搭建
新建一个Windows服务项目 nuget安装Quartz.NET,我这边使用的是2.3.3版本 1. Service改名 2. 添加安装程序,改名 3. ServiceInstaller->属 ...
- 迅为电子iTOP-HMI043 4.3寸人机界面产品
4.3寸人机界面: 7寸人机界面: 10.2寸人机界面: 产品认证CE:符合EN61000-6-2:2005, EN61000-6-4:2007标准FCC 兼容性:符合FCC Class A面板防护等 ...
- 【VBA研究】如何用Base64 编解码方法实现简单的加解密
Base64编码的思想是是采用64个基本的ASCII码字符对数据进行重新编码,将数据变成字符串实现文本传输.由于编码简单,所以很容易实现,代码也是现成的.利用这个编码规则可以实现简单的加解密.编解码方 ...
- 检查sql对象是否存在
SQL Server判断对象是否存在 1 判断数据库是否存在 Sql代码 if exists (select * from sys.databases where name = '数据库名') ...
- myeclipse出现Failed to load JavaHL Library.
eclipse启动出现如图的状况: 解决方法: Window-Preferences-Team-SVN,在SVN接口的下拉框可以看到,默认选择的是JavaHL(JNI) Not Available,手 ...
- ORACLE中的游标Cursor总结
游标(Cursor):用来查询数据库,获取记录集合(结果集)的指针,可以让开发者一次访问一行结果集,在每条结果集上作操作. 游标可分为: 1. 静态游标:分为显式(explicit)游标和 ...
- Python 软件开发目录规范
目录规范: ATM #工程文件夹 ------| bin #用来存放可执行文件的 |---- start.py conf #用来存放配置信息的 |---- settings.py lib ...
- Ubuntu环境修改IP地址方法
ubuntu环境修改IP地址方法和CentOS系统修改方法不太一样.ubuntu系统修改IP地址方法如下: 编辑/etc/network/interfaces,增加以下内容: auto eth0 if ...
- [Python3网络爬虫开发实战] 1.9.2-Scrapyd的安装
Scrapyd是一个用于部署和运行Scrapy项目的工具,有了它,你可以将写好的Scrapy项目上传到云主机并通过API来控制它的运行. 既然是Scrapy项目部署,基本上都使用Linux主机,所以本 ...