事务概念
事务是指一组最小逻辑操作单元,里面有多个操作组成。 组成事务的每一部分必须要同时提交成功,如果一个操作失败,整个操作就回滚。
事务ACID特性
- 原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
- 一致性(Consistency)
事务必须使数据库从一个一致性状态变换到另外一个一致性状态。
- 隔离性(Isolation)
事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
- 持久性(Durability)
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响
核心api
|-- Connection
void setAutoCommit(boolean autoCommit) ; 设置事务是否自动提交
如果设置为false,表示手动提交事务。
void commit() (); 手动提交事务
void rollback() ; 回滚(出现异常时候,所有已经执行成功的代码需要回退到事务开始前的状态。)
案例(张三给李四转账)
- 代码
package cn.persistXl.app;
import cn.persistXl.util.JdbcUtil;
import org.junit.Test;
import java.sql.*;
/**
* @author persistXL
* @data 2018/4/30 20:25
*/
public class AccountDao {
//全局参数
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
//转账,没有使用事物
public void trans() {
//准备sql
String sql_zs = "";
String sql_ls = "";
try {
//获取连接
conn = JdbcUtil.getConnection();
//使用默认开启的隐士事物
/**
* 第一次执行sql
*/
//预编译sql
pstmt = conn.prepareStatement(sql_zs);
//设置参数
//执行sql
pstmt.executeUpdate();
/**
* 第二次执行sql
*/
//预编译sql
pstmt = conn.prepareStatement(sql_ls);
//设置参数
//执行sql
pstmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally {
JdbcUtil.close(conn,pstmt,null);
}
}
//使用事物
public void trans1(){
//准备sql
String sql_zs = "";
String sql_ls = "";
try {
//获取连接
conn = JdbcUtil.getConnection();
//设置事物为手动提交
conn.setAutoCommit(false);
/**
* 第一次执行sql
*/
//预编译sql
pstmt = conn.prepareStatement(sql_zs);
//设置参数
//执行sql
pstmt.executeUpdate();
/**
* 第二次执行sql
*/
//预编译sql
pstmt = conn.prepareStatement(sql_ls);
//设置参数
//执行sql
pstmt.executeUpdate();
} catch (Exception e) {
try {
// 出现异常需要回滚事物
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}finally {
try {
//所有操作执行成功,提交事物
conn.commit();
JdbcUtil.close(conn,pstmt,null);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//使用事物,回滚到指定的代码段
public void trans2() {
Savepoint sp = null;
//准备sql
String sql_zs1 = "";
String sql_ls1 = "";
String sql_zs2 = "";
String sql_ls2 = "";
try {
//获取连接
conn = JdbcUtil.getConnection();
conn.setAutoCommit(false);
/*** 第一次转账 */
/**
* 第一次执行sql
*/
//预编译sql
pstmt = conn.prepareStatement(sql_zs1);
//执行sql
pstmt.executeUpdate();
/**
* 第二次执行sql
*/
//预编译sql
pstmt = conn.prepareStatement(sql_ls1);
//执行sql
pstmt.executeUpdate();
//回滚到这个位置
sp = conn.setSavepoint("trans");
/*** 第二次转账 */
pstmt = conn.prepareStatement(sql_zs2);
pstmt.executeUpdate();
pstmt = conn.prepareStatement(sql_ls2);
pstmt.executeUpdate();
} catch (Exception e) {
try {
//回滚到指定位置
conn.rollback(sp);
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}finally {
JdbcUtil.close(conn,pstmt,null);
}
}
}