13.7.2 JDBC的事务支持
JDBC
连接也提供了事务支持,JDBC
连接的事务支持由Connection
提供, Connection
默认打开自动提交,即关闭事务,在这种情况下,每条SQL
语句一旦执行,便会立即提交到数据库,永久生效,无法对其进行回滚操作。
可以调用Connection
的setAutoCommit()
方法来关闭自动提交,开启事务,如下代码所示:
connection.setAutoCommit(false);
程序中还可调用Connection
提供的getAutoCommit()
方法来返回该连接的自动提交模式。
旦事务开始之后,程序可以像平常一样创建Statement
对象,创建了Statement
对象之后,可以执行任意多条DML
语句,如下代码所示:
1 2 3
| statement.executeUpdate(...); statement.executeUpdate(...); statement.executeUpdate(...);
|
上面这些SQL
语句虽然被执行了,但这些SQL
语句所做的修改不会生效,因为事务还没有结束。如果所有的SQL
语句都执行成功,程序可以调用Connection
的commit()
方法来提交事务,如下代码所示:
connection.commit();
如果任意一条SQL
语句执行失败,则应该用Connection
的rollback
方法来回滚事务,如下代码所示:
connection.rollback();
实际上,当Connection
遇到一个未处理的SQLException
异常时,系统将会非正常退出,事务也会自动回滚。但如果程序捕获了该异常,则需要在异常处理块中显式地回滚事务.
实例 出现SQLException时,如果不捕获则系统自动回滚
下面程序示范了当程序出现未处理的SQLException
异常时,系统将自动回滚事务。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| import java.sql.*; import java.io.*; import java.util.*;
public class TransactionTest { private String driver; private String url; private String user; private String pass; public void initParam(String paramFile) throws Exception { Properties props = new Properties(); props.load(new FileInputStream(paramFile)); driver = props.getProperty("driver"); url = props.getProperty("url"); user = props.getProperty("user"); pass = props.getProperty("pass"); } public void insertInTransaction(String[] sqls) throws Exception { Class.forName(driver); try (Connection conn = DriverManager.getConnection(url, user, pass)) { conn.setAutoCommit(false); try ( Statement stmt = conn.createStatement()) { for (String sql : sqls) { stmt.executeUpdate(sql); } } conn.commit(); } } public static void main(String[] args) throws Exception { TransactionTest tt = new TransactionTest(); tt.initParam("mysql.ini"); String[] sqls = new String[] {"insert into student_table values(null , 'aaa' ,1)", "insert into student_table values(null , 'bbb' ,1)", "insert into student_table values(null , 'ccc' ,1)", "insert into student_table values(null , 'ccc' ,5)" }; tt.insertInTransaction(sqls); } }
|
上面程序中的有开启事务、提交事务的代码,并没有回滚事务的代码。但当程序执行到第4条SQL
语句(①处代码)时,这条语句将会引起外键约束异常,由于我们没有捕获处理该异常,所以事务会自动回滚。
Connection对象中间的方法
Connection
提供了两个方法来设置中间点。
Savepoint setSavepoint()
:在当前事务中创建一个未命名的中间点,并返回代表该中间点的Savepoint
对象。
Savepoint setSavepoint(String name)
:在当前事务中创建一个具有指定名称的中间点,并返回代表该中间点的Savepoint
对象。
通常来说,设置中间点时没有太大的必要指定名称,因为Connection
回滚到指定中间点时,并不是根据名字回滚的,而是根据中间点对象回滚的, Connection
提供了rollback(Savepoint savepoint)
方法回滚到指定中间点。
预览: