JDBC事务处理
程序员文章站
2022-03-06 18:34:58
...
1. 事务的概念
2. MySQL对事务的支持
3. JDBC事务处理
4. 事务保存点
事务处理在数据库开发中有着非常重要的作用,所谓事务就是所有的操作要么一起成功,要么一起失败,事务本身具有原子性(Atomicity)、一致性(Consistency)、隔离性或独立性(Isolation)、持久性(Durability)4个特性,这4个特性也被称为ACID特征。 原子性:原子性是事务最小的单元,是不可再分隔的单元,相当于一个个小的数据库操作,这些操作必须同时成功,如果一个失败了,则一切的操作将全部失败。 一致性:指的是在数据库操作的前后是完全一致的,保证数据的有效性,如果事务正常操作则系统会维持有效性,如果事务出现了错误,则回到最原始状态,也要维持其有效性,这样保证事务开始时和结束时系统处于一致状态。 隔离性:多个事务可以同时进行且彼此之间无法访问,只有当事务完成最终操作时,才可以看到结果。 持久性:事务完成之后,它对于系统的影响是永久性的。该修改即使出现致命的系统故障也将一直保持。
2. MySQL对事务的支持
序号 命令 描述 1 SET AUTOCOMMIT=0 取消自动提交处理,开启事务处理 2 SET AUTOCOMMIT=1 打开自动提交处理,关闭事务处理 3 START TRANSACTION 启动事务 4 BEGIN 启动事务,相当于执行 START TRANSACTION 5 COMMIT 提交事务 6 ROLLBACK 回滚全部事务 7 SAVEPOINT 事务保存点名称 设置事务保存点 8 ROLLBACK TO SAVEPOINT 保存点名称 回滚操作到保存点
3. JDBC事务处理
4. 事务保存点
create table t_account ( id int(11) not null auto_increment, accountname varchar(20) default null, accountbalance int(11) default null, primary key (id) ) engine=innodb auto_increment=3 default charset=utf8; insert into t_account(id,accountName,accountBalance) values (1,'张三',500),(2,'李四',1000); Demo01.java package com.andrew.jdbc.chap09; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import com.andrew.jdbc.util.DbUtil; public class Demo01 { private static DbUtil dbUtil = new DbUtil(); // 转出 private static void outCount(Connection con, String accountName, int account) throws Exception { String sql = "update t_account set accountBalance=accountBalance-? where accountName=?"; PreparedStatement pstmt = con.prepareStatement(sql); pstmt.setInt(1, account); pstmt.setString(2, accountName); pstmt.executeUpdate(); } // 转入 private static void inCount(Connection con, String accountName, int account) throws Exception { String sql = "update t_account set accountBalance=accountBalance+? where accountName=?"; PreparedStatement pstmt = con.prepareStatement(sql); pstmt.setInt(1, account); pstmt.setString(2, accountName); pstmt.executeUpdate(); } public static void main(String[] args) { Connection connection = null; try { connection = dbUtil.getConnection(); connection.setAutoCommit(false); // 取消自动提交 System.out.println("张三开始向李四转账!"); int account = 500; outCount(connection, "张三", account); inCount(connection, "李四", account); System.out.println("转账成功!"); } catch (Exception e) { try { connection.rollback(); // 回滚 } catch (SQLException e1) { e1.printStackTrace(); } e.printStackTrace(); } finally { try { connection.commit(); // 提交事务 connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } } 张三开始向李四转账! 转账成功! 500 1000 -> 0 1500 如果修改sql语句报错则不能执行
Demo02.java package com.andrew.jdbc.chap09; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Savepoint; import com.andrew.jdbc.util.DbUtil; public class Demo02 { private static DbUtil dbUtil = new DbUtil(); // 转出 private static void outCount(Connection con, String accountName, int account) throws Exception { String sql = "update t_account set accountBalance=accountBalance-? where accountName=?"; PreparedStatement pstmt = con.prepareStatement(sql); pstmt.setInt(1, account); pstmt.setString(2, accountName); pstmt.executeUpdate(); } // 转入 private static void inCount(Connection con, String accountName, int account) throws Exception { String sql = "update t_account set account=accountBalance+? where accountName=?"; PreparedStatement pstmt = con.prepareStatement(sql); pstmt.setInt(1, account); pstmt.setString(2, accountName); pstmt.executeUpdate(); } public static void main(String[] args) { Connection connection = null; Savepoint savepoint = null; try { connection = dbUtil.getConnection(); connection.setAutoCommit(false); // 取消自动提交 System.out.println("张三开始向李四转账!"); int account = 500; outCount(connection, "张三", account); savepoint = connection.setSavepoint(); // 设置一个保存点 inCount(connection, "李四", account); System.out.println("转账成功!"); } catch (Exception e) { try { connection.rollback(savepoint); // 回滚到savepoint保存点 } catch (SQLException e1) { e1.printStackTrace(); } e.printStackTrace(); } finally { try { connection.commit(); // 提交事务 connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } } 运行结果: 张三开始向李四转账! com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'account' in 'field list' 500 1000 -> 0 1000