对数据库进行并发操作时,为了避免由于并发操作带来的问题,一般要将同一个任务中对数据库的增、删、改、查操作编写到一个事务中,同一个事务中的所有操作要么全部执行成功,要么都不执行。因此JDBC也提供了对事务开发的支持,本节将向读者介绍JDBC中有关事务开发的知识。
事务介绍
事物是SQL中的单个逻辑工作单元,一个事务内的所有语句被作为整体执行,遇到错误时,可以回滚事务,取消事务所做的所有改变,从而可以保证数据库的一致性和可恢复性。
一个事务逻辑工作单元必须具有以下4种属性,包括原子性、一致性、隔离性和永久性。原子性是指一个事务必须作为一个原子单位,它所做的数据修改操作要不全部执行,要不全部取消。一致性是指当事务完成后,数据必须保证处于一致性的状态。隔离是指一个事务所做的修改必须能够跟其他事务所作的修改分离开来,以免在并发处理时,发生数据错误。永久性是指事务完成后,它对数据库所做的修改应该被永久保持。
进行事务操作主要使用Connection对象中的三个方法。setAutoCommit方法是指将此连接的自动提交模式设置为给定状态。如果参数autoCommit的值为true,则每执行一句SQL命令将自动被作为单个事务提交;否则,其将所有SQL语句聚集到一个事务中,直到调用commit方法或rollback方法为止,其默认值为true。
注意:如果参数autoCommit的值为true,则每执行一句SQL命令将自动被作为单个事务提交;否则,其将所有SQL语句聚集到一个事务中,直到调用commit方法或rollback方法为止,其默认值为true。
commit方法是指提交当前的事务,并自动开始下一个事务。执行此方法后,会释放此Connection对象当前持有的所有数据库锁,同时要注意此方法只应该在自动提交模式被禁用的情况下使用。
rollback方法是指回滚当前的事务,并自动开始下一个事务。执行此方法后,会释放此Connection对象当前持有的所有数据库锁,同时要注意此方法只应该在自动提交模式被禁用的情况下使用。
17.6.2 进行事务操作
对事务有了一个基本了解后,在本节中就通过程序的形式来了解如何进行事务操作。
【范例17-2】示例代码17-2是一个进行事务操作的程序。
示例代码17-2
01 import java.sql.*;
02 public class ShuJuKu2
03 {
04 public static void main(String[] args)
05 {
06 //声明Connection引用
07 Connection con=null;
08 //声明Oracle数据库的连接字符串、用户名及密码
09 String url="jdbc:odbc:student";
10 String user="";
11 String password="";
12 try
13 {
14 //加载Oracle驱动类
15 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
16 //创建数据库连接
17 con=DriverManager.getConnection(url,user,password);
18 //禁用自动提交模式,开始一个事务
19 con.setAutoCommit(false);
20 //创建Statement对象
21 Statement stat=con.createStatement();
22 System.out.println("查询原数据库内记录");
23 myVoid(stat);
24 //向表中插入一行记录
25 stat.executeUpdate("insert into student values('200801','Tom', '23','123456789')");
26 //再次向表中插入一行记录
27 stat.executeUpdate("insert into student values('200802', 'Lucy','23','555555555')");
28 System.out.println("插入记录后数据库内记录");
29 myVoid(stat);
30 //将事务提交
31 con.commit();
32 //恢复自动提交模式
33 con.setAutoCommit(true);
34 //关闭语句
35 stat.close();
36 }
37 catch(Exception e)
38 {//如果出现错误将发起回滚操作
39 e.printStackTrace();
40 try
41 {
42 con.rollback();
43 System.out.println("出现异常,事务回滚");
44 }
45 catch(Exception ae)
46 {
47 e.printStackTrace();
48 }
49 }
50 finally
51 {
52 try
53 {
54 //关闭数据库连接
55 con.close();
56 }
57 catch(Exception e)
58 {
59 e.printStackTrace();
60 }
61 }
62 }
63 //自定义的检索music表全表的方法
64 public static void myVoid(Statement stat) throws SQLException
65 {
66
67 ResultSet rs=stat.executeQuery("select * from student");
68 //打印表头信息
69 System.out.println("学号\t姓名\t\t年龄\t电话");
70 //循环打印结果集中的每一条记录
71 while(rs.next())
72 {
73 //获取当前记录中第一列内容
74 String sid=rs.getString(1);
75 //获取当前记录中第二列内容
76 String sname=rs.getString(2);
77 //获取当前记录中第三列内容
78 String sage=rs.getString(3);
79 //获取当前记录中第四列内容
80 String stel=rs.getString(4);
81 //打印本条记录的内容
82 System.out.println(sid+""+sname+""+sage+""+stel);
83 }
84 //关闭结果集
85 rs.close();
86 }
87 }
【运行结果】使用javac编译程序将产生一个和该程序对应的class程序,然后使用Java运行编译产生的class程序,运行结果如图17-19所示。
再次运行程序,运行结果如图17-20所示。
【代码解析】在本程序中使用了提交事务和回滚事务。在本程序中先获取数据库中本身的记录,然后插入两条语句后,再来获取记录,程序的第31行使用了事务提交。从而实现插入效果。但是再次运行程序,因为数据库中已经存在要插入的记录,所以再次插入会发生异常,从而在catch语句中进行回滚事务。 http://www.china-pub.com/195064
【书名】21天学通Java
【作者】庞永庆 庞丽娟 等编著
【ISBN】978-7-121-07897-2
【出版社】电子工业出版社
【出版日期】2009年1月
【宣传语】
项目综合练习典型实例核心技术基础知识案例
307个典型实例、1个项目案例、246个练习题
一线开发人员全程贴心讲解,上手毫不费力
20小时多媒体语音视频教学
本书源代码 + 本书电子教案(PPT)
1000余页编程参考宝典电子书(免费赠送)