一、事务的概念
事物处理在数据库开发中有着非常重要的作用,所谓事务就是所有的操作要么一起成功,要么一起失败,事物本身具有原子性(Atomicity)、一致性(Conststency)、隔离性或独立性(Isolation)、持久性(Durablilty)4哥特性,这4个特性也被称为ACID特征。
原子性:原子性时事务最小单元,是不可再分隔的单元,相当于一个个小的数据库操作,这些操作必须同时成功,如果一个失败了,则一切的操作将全部失败。
一致性:指的是在数据库操作的前后是完全一致的,保证数据的有效性,如果事务正常操作,则系统会维持有效性,如果事务出现了错误,则回到原始状态,也要维持其有效性,这样保证事务开始时和结束时系统处于一致状态。
隔离性/独立性:多个事务可以同时进行且彼此之间无法访问,只有当事务完成最终操作时,才可以看到结果;
持久性:事务完成之后,它对与系统的影响是永久性的。该修改即使出现致命的系统故障也将一直保持。
二、MySql对事务的支持
三、JDBC事务处理
demo:
con.setAutoCommit(false);//取消自动提交
con.rollback();//回滚
con.commit();//提交事务
package com.java1234.jdbc.day09;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import com.java1234.jdbc.util.DbUtil;
public class Demo1 {
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.executeQuery();
}
public static void main(String[] args) {
Connection con = null;
try {
con = dbUtil.getCon();
con.setAutoCommit(false);//取消自动提交
System.out.println("张三开始向李四转账");
int account=500;
outCount(con,"张三",account);
inCount(con,"李四",account);
System.out.println("转账成功");
} catch (Exception e) {
try {
con.rollback();//回滚
} catch (SQLException e1) {
e1.printStackTrace();
}//回滚
e.printStackTrace();
}finally {
try {
con.commit();//提交事务
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
四、事务保存点
Savepoint sp = null;
sp = con.setSavepoint();//设置一个保存点
con.rollback(sp);//回滚道sp保存点
package com.java1234.jdbc.day09;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Savepoint;
import com.java1234.jdbc.util.DbUtil;
public class Demo1 {
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.executeQuery();
}
public static void main(String[] args) {
Connection con = null;
Savepoint sp = null;
try {
con = dbUtil.getCon();
con.setAutoCommit(false);//取消自动提交
System.out.println("张三开始向李四转账");
int account=500;
outCount(con,"张三",account);
sp = con.setSavepoint();//设置一个保存点
inCount(con,"李四",account);
System.out.println("转账成功");
} catch (Exception e) {
try {
con.rollback(sp);//回滚道sp保存点
} catch (SQLException e1) {
e1.printStackTrace();
}//回滚
e.printStackTrace();
}finally {
try {
con.commit();//提交事务
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}