基本概念:
事务使指一组最小逻辑操作单元,里面有多个操作组成。 组成事务的每一部分必须要同时提交成功,如果有一个操作失败,整个操作就回滚。
事务ACID特性
l 原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
l 一致性(Consistency)
事务必须使数据库从一个一致性状态变换到另外一个一致性状态。
l 隔离性(Isolation)
事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
l 持久性(Durability)
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响
事务的特性:
原子性,是一个最小逻辑操作单元 !
一致性,事务过程中,数据处于一致状态。
持久性, 事务一旦提交成功,对数据的更改会反映到数据库中。
隔离性, 事务与事务之间是隔离的。
案例
需求: 张三给李四转账
设计: 账户表
技术:
|-- Connection
void setAutoCommit(boolean autoCommit) ; 设置事务是否自动提交
如果设置为false,表示手动提交事务。
void commit() (); 手动提交事务
void rollback() ; 回滚(出现异常时候,所有已经执行成功的代码需要回退到事务开始前的状态。)
Savepoint setSavepoint(String name)
-- 账号表 CREATE TABLE account( id INT PRIMARY KEY AUTO_INCREMENT, accountName VARCHAR(20), money DOUBLE )
java:
package js; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Savepoint; public class AccountDao { //全局参数 private Connection conn; private PreparedStatement pstmt; private String sql_zs="UPDATE account SET money=money-1000 WHERE accountName='张三'"; private String sql_ls="UPDATE account SET money=money+1000 WHERE accountName='李四'"; private String sql_zs1="UPDATE account SET money=money-500 WHERE accountName='张三'"; private String sql_ls1="UPDATE1 account SET money=money+500 WHERE accountName='李四'"; //1.转账 没有使用事务 public void trans(){ try { //创建连接 conn=JdbcUtil.getConnection();//默认开启的隐士事务 //创建pstmt对象 //第一次执行Sql pstmt=conn.prepareStatement(sql_zs); pstmt.executeUpdate(); //第二次执行sql pstmt=conn.prepareStatement(sql_ls); pstmt.executeUpdate(); } catch (Exception e) { throw new RuntimeException(); }finally{ JdbcUtil.close(conn, pstmt, null); } } /* * 使用事务 */ public void trans1(){ try { //创建连接 conn=JdbcUtil.getConnection();//默认开启的隐士事务 conn.setAutoCommit(false); //创建pstmt对象 //第一次执行Sql pstmt=conn.prepareStatement(sql_ls); pstmt.executeUpdate(); //第二次执行sql pstmt=conn.prepareStatement(sql_zs); pstmt.executeUpdate(); } catch (Exception e) { try { conn.rollback(); } catch (SQLException e1) { throw new RuntimeException(); } }finally{ try { conn.commit(); JdbcUtil.close(conn, pstmt, null); } catch (SQLException e) { throw new RuntimeException(); } } } /* * 回滚到指定位置 */ public void trans2(){ Savepoint sp=null; try { //创建连接 conn=JdbcUtil.getConnection();//默认开启的隐士事务 conn.setAutoCommit(false); //创建pstmt对象 //第一次转账 //第一次执行Sql pstmt=conn.prepareStatement(sql_ls); pstmt.executeUpdate(); //第二次执行sql pstmt=conn.prepareStatement(sql_zs); pstmt.executeUpdate(); //设置回滚位置 sp=conn.setSavepoint(); //第二次转账 //第一次执行Sql pstmt=conn.prepareStatement(sql_ls1); pstmt.executeUpdate(); //第二次执行sql pstmt=conn.prepareStatement(sql_zs1); pstmt.executeUpdate(); } catch (Exception e) { try { conn.rollback(sp); } catch (SQLException e1) { throw new RuntimeException(); } }finally{ try { conn.commit(); JdbcUtil.close(conn, pstmt, null); } catch (SQLException e) { throw new RuntimeException(); } } } }