现在的位置: 首页 > 综合 > 正文

JDBC中的事务支持

2013年10月26日 ⁄ 综合 ⁄ 共 1787字 ⁄ 字号 评论关闭

数据库中事务(transaction)的主要目的是让数据库从一个稳定的状态变化到另一个稳定的状态。当数据库中进行提交时,应该保证所有的变化都已经保存了;如果进行回滚,那么所有的变化都不保存。

在jdbc中,事务的启动是有jdbc驱动自动完成的,而事务的终止则可以是自动也可以是手动。事务自动终止还是手动终止是由连接的自动提交状态来判断的,对于jdbc,默认的自动提交状态是true,也就是说事务由驱动自动提交,何时终止依赖于执行哪种sql命令,如下表

语句类型   事务提交时间
insert,update,delete  executeUpdate()或execute()返回时

select    Result对象中所有行都读取完毕,或用一个Statement对象在同一个连接上执行新的sql命令

在实际的项目应用中,数据库几乎都是多用户应用或者一个任务要访问多个表,因此需要我们手动来管理事务。
Connection类提供的管理事务的方法如下:
*void setAutoCommit(boolean);设置自动提交为true(默认为自动提交事务)或false(需要显示的提交事务)
*void commit();提交当前事务。自从上次提交或回滚之后的所有变化将被提交。
*void close();属于事务管理的隐含部分。关闭Connection可能会引起事务被提交(确切行为依赖数据库,jdbc没有规定)
*void rollback();数据库返回到执行当前事务之前的状态
*Savepoint setSavePoint();在当前事务中创建一个没有名称的保存点,并返回这个Savepoint对象。
*Savepoint setSavePoint(String);在当前事务中创建一个有名称的保存点,并返回这个Savepoint对象。
*void releaseSavepoint(Savepoint);从当前事务中删除给定的保存点
*void rollback(Savepoint);回滚在给定的保存点创建之后所产生的变化。

下面来看一下事务的例子,如经典的银行转账问题。

在没使用手动管理事务之前,转账代码如下:
......
try
{
 Statement stmt=connection.createStatement();
 stmt.executeUpdate("update account set balance=balance-100 where user='a'");
 stmt.executeUpdate("update account set balance=balance+100 where user='b'");
}
catch(SQLException ex)
{
 System.out.println("转账失败:"+ex);
}
......
上面sql语句的功能很简单,用户a从他的帐户中转100元到用户b的帐户中。默认情况下,jdbc的事务提交是自动的,那么上面的过程就涉及到了两个事务(第一个事务在第一条executeUpdate执行完后提交,第二个事务在第二条executeUpdate执行完后提交),如果这两条语句都正常执行,那么ok,不会出现问题;如果第一条executeUpdate出现异常,那么会报告转账失败,两个事务都没执行,问题也不大(至少数据库还是保持一致的);然而,第二条executeUpdate出现异常时,此时数据库就出现了不一致的行为。

使用手动管理事务之后,转账代码如下:
......
connection.setAutoCommit(false); //设置为手动提交事务
try
{
 Statement stmt=connection.createStatement();
 stmt.executeUpdate("update account set balance=balance-100 where user='a'");
 stmt.executeUpdate("update account set balance=balance+100 where user='b'");
 connection.commit();
}
catch(SQLException ex)
{
 connection.rollback();
 System.out.println("转账失败:"+ex);
}
......
具体就不解释了。 

 

【上篇】
【下篇】

抱歉!评论已关闭.