JAVA事务系列二:JDBC事务

事务的提交和回滚:

在JDBC API中,默认的情况为自动提交事务和回滚事务,也就是说,每一条对数据库的更新的sql语句代表一项事务,操作成功后,系统自动调用commit()来提交,否则将调用rollback()来撤消事务。

可以通过调用setAutoCommit(false) 来禁止自动提交事务。然后把多条更新数据库的sql语句做为一个事务,在所有操作完成之后,调用commit()来进行整体提交。倘若其中一项 sql操作失败,就不会执行commit()方法,而是产生相应的sqlexception,此时就可以捕获异常代码块中调用rollback()方法撤消事务。

public int delete(int sID) {   dbc = new DataBaseConnection();   Connection con = dbc.getConnection();   try {    con.setAutoCommit(false);// 更改JDBC事务的默认提交方式    dbc.executeUpdate("delete from xiao where delete from xiao_content where delete from xiao_affix where bylawid=" + sID);    con.commit();//提交JDBC事务    con.setAutoCommit(true);// 恢复JDBC事务的默认提交方式    dbc.close();    return 1;   }   catch (Exception exc) {    con.rollBack();//回滚JDBC事务    exc.printStackTrace();    dbc.close();    return -1;   } }

以上代码我们手动处理JDBC事务,JDBC的数据库连接对象Connection提供了三种事务控制方式:

(1) setAutoCommit(Boolean autoCommit):设置是否自动提交事务;

(2) commit();提交事务;

(3) rollback();撤消事务;

注:事务周期限于Connection的生命周期。JDBC 事务的一个缺点是事务的范围局限于一个数据库连接。一个 JDBC 事务不能跨越多个数据库。

JDBC事务隔离级别:

JDBC定义了五种事务隔离级别:

TRANSACTION_NONE 说明不支持事务。

TRANSACTION_READ_UNCOMMITTED 说明在提交前一个事务可以看到另一个事务的变化。这样脏读、不可重复的读和虚读都是允许的。

脏读:在没有提交数据时能够读到已经更新的数据

TRANSACTION_READ_COMMITTED 说明读取未提交的数据是不允许的。这个级别仍然允许不可重复的读和虚读产生。

不可重复的读:在一个事务中进行查询时,允许读取提交前的数据,数据提交后,当前查询就可以读取到数据。update数据时候并不锁住表

TRANSACTION_REPEATABLE_READ 说明事务保证能够再次读取相同的数据而不会失败,但虚读仍然会出现。

虚读:允许读取到其他事务提交的新增数据

TRANSACTION_SERIALIZABLE 是最高的事务级别,它防止脏读、不可重复的读和虚读,在一个事务中进行查询时,不允许任何对这个查询表的数据修改。

在JDBC中,通过如下API设置事务隔离级别

conn.setTransactionLevel(TRANSACTION_SERIALIZABLE) ; int level = conn.getTransactionIsolation();

保存点(SavePoint):

JDBC定义了SavePoint接口,提供了一个更细粒度的事务控制机制。当设置了一个保存点后,可以rollback到该保存点处的状态,而不是rollback整个事务。

Connection接口的setSavepoint和releaseSavepoint方法可以设置和释放保存点。

Savepoint sp = conn.setSavepoint(); Conn.rollback(sp); Conn.commit(); //回滚后必须要提交

JDBC规范虽然定义了事务的以上支持行为,但是各个JDBC驱动,数据库厂商对事务的支持程度可能各不相同。如果在程序中任意设置,可能得不到想要的效果。