下面介绍如何把一系列语句组织成一个事务?如果事务中所有命令都能正确执行,就可以提交这个事务;否则,如果事务中有一个命令出现错误,回滚这个事务,并返回到提交之前的状态,好像什么也没有发生。把命令组合成事务的主要原因是保证数据库的完整性。对于一个事务而言,要么事务中语句全部得到正确执行,事务就可被提交了,要么它中间出现错误。后一种情况,可以调用rollback()方法,数据库将自动放弃上一次提交事务以来的全部变化。一个数据库连接的缺省模式是autocommit模式,每个SQL命令一执行就会提交给数据库。一旦某个命令已提交,就不能把它回退。可以用Connection接口的getAutocommit()方法,检验数据库的目前自动提交模式设置。用命令con.setAutoCommit(false)方法关闭自动提交模式。用con.commit()命令提交事务。用con.rollback()回滚一个事务。
代码
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import javax.naming.NamingException;
public class UseTran {
public static void main(String[] args) {
Connection con = null;// 方法里临时变量要手动初始化
PreparedStatement updateAge = null;
String updateString = "update student "
+ "set age = ? where name like ?";
String jndiname = "jdbcPool/mydatasource";
try {
con = DBCon.getConnectionFromPooledDataSource(jndiname);
updateAge = con.prepareStatement(updateString);
int[] age = { 45, 39, 25, 96 };
String[] names = { "梁朝伟%", "贝壳汗母%", "小罗%", "霍元甲%" };
int len = age.length;
// 设置事务提交模式为非自动提交
con.setAutoCommit(false);
for (int i = 0; i < len; i++) {
updateAge.setInt(1, age[i]);
updateAge.setString(2, names[i]);
updateAge.executeUpdate();
}
// 上面执行的语句,如果不出现异常则提交 SQL 语句
con.commit();
System.out.println("update success!");
} catch (NamingException ex) {
System.err.println("Name Not Bound : " + ex.getMessage());
} catch (SQLException ex) {
System.err.println("SQLException: " + ex.getMessage());
if (con != null) {
try {
System.err.print("Transaction is being ");
System.err.println("rolled back");
// 如果出现异常则事务回滚
con.rollback();
} catch (SQLException excep) {
System.err.print("SQLException: ");
System.err.println(excep.getMessage());
}
}
} finally {// 不管发生不发生异常,要关闭连接,释放资源
try {
if (con != null) {
con.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}