1.概述
在一个事件中,有多个组成单元,这些单元要么全部成功,要么全部失败,这个事件就可以称之为一个事务。
2. 案例:转账
update user set money = money -100 where name= ‘a’;
update user set money = money +100 where name= ‘b’;
为了保证两句sql同时成功或失败,需要将它们写入一个数据库的事务当中。
3. 在Mysql客户端中书写事务
数据库中事务里的sql语句,可以选择提交或回滚。如果提交,数据库中的数据,才会发生真实修改。如果回滚,数据库的数据,会恢复到修改之前的状态。
a.sql语句:
4.使用JDBC控制事务
在jdbc中,一个sql语句就是一个事务。现在需要多条sql位于一个事务中,所以需要开启事务。
a.代码实现:
package cn.tedu.trans;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
//事务测试
public class TransDemo1 {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/ajaxtxdy", "root", "123456");
//开启事务
conn.setAutoCommit(false);//默认值为true,代表会自动提交。
//自动提交意味着一句sql就是一个事务,执行sql就会立刻提交这个事务,修改数据库中的数据。
//设置为false,代表不会自动提交,表示开启事务,需要手动提交或回滚。
ps = conn.prepareStatement("update user set money = money -100 where name=?");
ps.setString(1, "a");
ps.executeUpdate();
int i =1/0;
ps = conn.prepareStatement("update user set money = money +100 where name = ?");
ps.setString(1, "b");
ps.executeUpdate();
conn.commit();//在sql书写完成之后,选择使用commit方法提交事务。
} catch (Exception e) {
if(conn !=null){
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
e.printStackTrace();
}finally{
if(conn !=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
conn = null;
}
}
if(rs !=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
rs = null;
}
}
if(ps !=null){
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
ps =null;
}
}
}
}
}
b.回滚到保存点
package cn.tedu.trans;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Savepoint;
//事务测试
public class TransDemo2 {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
Savepoint sp =null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day16", "root", "root");
conn.setAutoCommit(false);//默认值为true,代表会自动提交。
ps = conn.prepareStatement("update user set money = money -100 where name=?");
ps.setString(1, "a");
ps.executeUpdate();
ps = conn.prepareStatement("update user set money = money +100 where name = ?");
ps.setString(1, "b");
ps.executeUpdate();
//添加保存点
sp = conn.setSavepoint();
ps = conn.prepareStatement("update user set money = money -100 where name=?");
ps.setString(1, "a");
ps.executeUpdate();
int i =1/0;
ps = conn.prepareStatement("update user set money = money +100 where name = ?");
ps.setString(1, "b");
ps.executeUpdate();
conn.commit();//在sql书写完成之后,选择使用commit方法提交事务。
} catch (Exception e) {
if(conn !=null){
try {
if(sp != null){
conn.rollback(sp);//回滚事务
//剩下的代码继续提交
conn.commit();
}
} catch (SQLException e1) {
e1.printStackTrace();
}
}
e.printStackTrace();
}finally{
if(conn !=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
conn = null;
}
}
if(rs !=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
rs = null;
}
}
if(ps !=null){
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
ps =null;
}
}
}
}
}