事务特征:原子性,一致性,独立性,持久性。
要想操作事务,必须按照以下步骤完成。
1,取消掉自动提交(SET AUTOCOMMIT=0):每次执行数据库更新的时候实际上发出SQL命令之后就已经提交上去了。
2,开始事务,
3,进行一系列操作
4,如果操作一切合格,则提交事务,
5,如果发现一个地方有问题,则可以回滚,
6,或者设置一个SAVEPOINT保存事务提交点。
在JDBC中,同样支持事务的处理操作。
一,不使用事务处理情况。
通过批处理插入数据:
package 类集; import java.sql.Connection ; import java.sql.DriverManager ; import java.sql.Statement ; public class TranDemo01{ // 定义MySQL的数据库驱动程序 public static final String DBDRIVER = "org.gjt.mm.mysql.Driver" ; // 定义MySQL数据库的连接地址 public static final String DBURL = "jdbc:mysql://localhost:3306/sys" ; // MySQL数据库的连接用户名 public static final String DBUSER = "root" ; // MySQL数据库的连接密码 public static final String DBPASS = "aaaaaa" ; public static void main(String args[]) throws Exception{ // 所有异常抛出 Connection conn = null ; // 数据库连接 Statement stmt = null ; // 定义数据库操作 Class.forName(DBDRIVER) ; // 加载驱动程序 conn = DriverManager.getConnection(DBURL,DBUSER,DBPASS) ; stmt = conn.createStatement() ; stmt.addBatch("INSERT INTO user(name,age,birthday)" + " VALUES ('LXH-1',11,'1975-03-05') ") ; stmt.addBatch("INSERT INTO user(name,age,birthday)" + " VALUES ('LXH-2',12,'1976-03-05') ") ; // 加入“'”之后,此SQL语法就出现了错误,所以,肯定执行到此语句的时候出现代码错误 stmt.addBatch("INSERT INTO user(name,age,birthday)" + " VALUES ('LXH-'3',13,'1977-06-01') ") ; stmt.addBatch("INSERT INTO user(name,age,birthday)" + " VALUES ('LXH-4',14,'1965-03-05') ") ; int temp[] = stmt.executeBatch() ; //返回更新数据量 System.out.println("更新了:" + temp.length+ "条数据。") ; stmt.close() ; conn.close() ; // 数据库关闭 } };
运行结果:
Sun Apr 23 00:09:39 CST 2017 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification. Exception in thread "main" java.sql.BatchUpdateException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '3',13,'1977-06-01')' at line 1 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at com.mysql.jdbc.Util.handleNewInstance(Util.java:425) at com.mysql.jdbc.Util.getInstance(Util.java:408) at com.mysql.jdbc.SQLError.createBatchUpdateException(SQLError.java:1162) at com.mysql.jdbc.StatementImpl.executeBatchInternal(StatementImpl.java:1048) at com.mysql.jdbc.StatementImpl.executeBatch(StatementImpl.java:958)
at 类集.TranDemo01.main(TranDemo01.java:29)
查询数据库:
发现,虽然程序报错了,但是批处理中其他语句却执行成功了。
以上操作只将错误数据空出,如果这5条记录有相互关系,则这样实现肯定不符合要求。
JDBC事务处理操作步骤
事务处理代码:
package 类集; import java.sql.Connection ; import java.sql.DriverManager ; import java.sql.SQLException ; import java.sql.Statement ; public class TranDemo02{ // 定义MySQL的数据库驱动程序 public static final String DBDRIVER = "org.gjt.mm.mysql.Driver" ; // 定义MySQL数据库的连接地址 public static final String DBURL = "jdbc:mysql://localhost:3306/sys" ; // MySQL数据库的连接用户名 public static final String DBUSER = "root" ; // MySQL数据库的连接密码 public static final String DBPASS = "aaaaaa" ; public static void main(String args[]) throws Exception{ // 所有异常抛出 Connection conn = null ; // 数据库连接 Statement stmt = null ; // 定义数据库操作 Class.forName(DBDRIVER) ; // 加载驱动程序 conn = DriverManager.getConnection(DBURL,DBUSER,DBPASS) ; conn.setAutoCommit(false) ; // 取消掉自动提交 stmt = conn.createStatement() ; stmt.addBatch("INSERT INTO user(name,age,birthday)" + " VALUES ('LXH-1',11,'1975-03-05') ") ; stmt.addBatch("INSERT INTO user(name,age,birthday)" + " VALUES ('LXH-2',12,'1976-03-05') ") ; // 加入“'”之后,此SQL语法就出现了错误,所以,肯定执行到此语句的时候出现代码错误 stmt.addBatch("INSERT INTO user(name,age,birthday)" + " VALUES ('LXH-'3',13,'1977-06-01') ") ; stmt.addBatch("INSERT INTO user(name,age,birthday)" + " VALUES ('LXH-4',14,'1965-03-05') ") ; try{ int temp[] = stmt.executeBatch() ; System.out.println("更新了:" + temp.length+ "条数据。") ; conn.commit() ; // 所有的操作成功了 }catch(Exception e){ try{ conn.rollback() ;
System.out.println("数据更新失败"); }catch(Exception e1){ } } stmt.close() ; conn.close() ; // 数据库关闭 } };
运行结果:
Sun Apr 23 00:20:38 CST 2017 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification. 数据更新失败
数据库查询:
可以发现并没有插入为报错的数据。
SAVEPOINT:
正常情况下,可以通过SAVEPOINT保存事务的操作点,默认情况下,回滚是将所有操作取消掉,而通过SAVEPOINT可以设置回退的位置。
一个Sessions的操作(每一个连接到数据库上的用户都称为一个Session)
操作1,
操作2
操作3,
SAVEPOINT 记录点1
操作4
操作5
RALLBACK 记录点1.
设置SAVEPOINT
Savepoint setSavepoint()
在当前事务中创建一个未命名的保存点 (savepoint),并返回表示它的新 Savepoint 对象。
实例代码:
package 类集; import java.sql.Connection ; import java.sql.DriverManager ; import java.sql.SQLException ; import java.sql.Statement ; import java.sql.Savepoint ; public class TranDemo03{ // 定义MySQL的数据库驱动程序 public static final String DBDRIVER = "org.gjt.mm.mysql.Driver" ; // 定义MySQL数据库的连接地址 public static final String DBURL = "jdbc:mysql://localhost:3306/sys" ; // MySQL数据库的连接用户名 public static final String DBUSER = "root" ; // MySQL数据库的连接密码 public static final String DBPASS = "aaaaaa" ; public static void main(String args[]) throws Exception{ // 所有异常抛出 Connection conn = null ; // 数据库连接 Statement stmt = null ; // 定义数据库操作 Class.forName(DBDRIVER) ; // 加载驱动程序 conn = DriverManager.getConnection(DBURL,DBUSER,DBPASS) ; conn.setAutoCommit(false) ; // 取消掉自动提交 stmt = conn.createStatement() ; stmt.executeUpdate("INSERT INTO user(name,age,birthday)" + " VALUES ('LXH-1',11,'1975-03-05') ") ; stmt.executeUpdate("INSERT INTO user(name,age,birthday)" + " VALUES ('LXH-2',12,'1976-03-05') ") ; Savepoint sp = conn.setSavepoint() ; // 设置保存点 stmt.executeUpdate("INSERT INTO user(name,age,birthday)" + " VALUES ('LXH-4',14,'1965-03-05') ") ; stmt.executeUpdate("INSERT INTO user(name,age,birthday)" + " VALUES ('LXH-5',15,'1965-08-05') ") ; try{ conn.rollback(sp) ; // 回滚到保存点 conn.commit() ; // 所有的操作成功了
System.out.println("程序出错,已经回滚到保存点。");
}catch(Exception e){ e.printStackTrace() ; } stmt.close() ; conn.close() ; // 数据库关闭 } };
程序结果:
Sun Apr 23 00:34:43 CST 2017 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification. 程序出错,已经回滚到保存点。
数据库查询:
可以发现,因为发生错误,所以发生回滚,回滚到保存点,保存点之前的数据都正常更新,之后的数据没有正常插入。
总结
事务的基本概念
如果数据库中处理事务
处理事务的步骤:1,取消提交,2,执行多条SQL语句。3,如果没有异常就提交事务。否则回滚。
保存点很少使用。