数据库事务
一组要么同时执行成功,要么同时执行失败的SQL语句。是数据库操作的一个执行单元
事务开始于
- 连接到数据库上,并执行一条DML语句insert、update或delete
- 前一个事务结束后,又输入了另一条DML语句
事务结束于
-
执行commit或rollback语句。
-
执行一条DDL语句,例如create table语句,在这种情况下,会自动执行commit语句。
-
执行一条DDL语句,例如grant语句,在这种情况下,会自动执行commit。
-
断开与数据库的连接。
-
执行了一条DML语句,该语句却失败了,在这种情况中,会为这个无效的DML语句执行rollback语
句。
事务的四大特点
- actomicity(原子性)
表示一个事务内的所有操作是一个整体,要么全部成功,要么全部失败 - consistency(一致性)
表示一个事务内有一个操作失败时,所有的更改过的数据都必须回滚到修改前状态 - isolation(隔离性)
事务查看数据时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事务修
改它之后的状态,事务不会查看中间状态的数据。 - durability(持久性)
持久性事务完成之后,它对于系统的影响是永久性的。
JDBC事务的应用
如果JDBC连接处于自动提交模式,默认情况下,则每个SQL语句在完成后都会提交到数据库。
事务使您能够控制是否和何时更改应用于数据库。它将单个SQL语句或一组SQL语句视为一个逻辑单
元,如果任何语句失败,则整个事务将失败。
要启用手动事务支持,而不是JDBC驱动程序默认使用的自动提交模式,请使用Connection对象的
setAutoCommit()方法。如果将boolean false传递给setAutoCommit(),则关闭自动提交。我
们可以传递一个布尔值true来重新打开它。
事务的提交和回滚
完成更改后,我们要提交更改,然后在连接对象上调用commit()方法,如下所示:
conn.commit( );
回滚更新
conn.rollback( );
Savepoints
新的JDBC 3.0 Savepoint接口提供了额外的事务控制。
设置保存点时,可以在事务中定义逻辑回滚点。如果通过保存点发生错误,则可以使用回滚方法来撤消
所有更改或仅保存在保存点之后所做的更改。
Connection对象有两种新的方法来帮助您管理保存点 -
- setSavepoint(String savepointName):定义新的保存点。它还返回一个Savepoint对象。
- releaseSavepoint(Savepoint savepointName):删除保存点。请注意,它需要一个Savepoint
对象作为参数。此对象通常是由setSavepoint()方法生成的保存点。
try{
//Assume a valid connection object conn
conn.setAutoCommit(false);
Statement stmt = conn.createStatement();
Savepoint savepoint1 = conn.setSavepoint("Savepoint1");
String SQL = "INSERT INTO Employees VALUES (106, 20, 'Rita', 'Tez')";
stmt.executeUpdate(SQL);
String SQL = "INSERTED IN Employees VALUES (107, 22, 'Sita', 'Tez')";
stmt.executeUpdate(SQL);
conn.commit();
}catch(SQLException se){
conn.rollback(savepoint1);
}
1、要取消掉JDBC的自动提交:void setAutoCommit(boolean autoCommit)
2、执行各个SQL语句,加入到批处理之中
3、如果所有语句执行成功,则提交事务 commit();如果出现了错误,则回滚:rollback()
try {
connection.setAutoCommit(false);
add(connection);
// int i = 1/0;
sub(connection);
System.out.println("===============");
connection.commit();
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("---------------");
try {
connection.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}