在jdbc中默认会自动提交事务
如果我们需要手动提交事务的时候 ,我们可以按照以下操作。
模拟转账情况:
这里话不多说直接上代码:
package mysql_jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* @author Hercules
* @version 创建时间:2020年6月12日 下午7:43:49
* 类说明
*/
public class Money {
public static void main(String[] args) {
money("a", "b", 1000);
}
public static void money(String from,String to,double money) {
//加载驱动
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//获取连接
Connection conn = null;
PreparedStatement pst = null;
//jdbc:mysql://主机地址:端口/数据库名
//jdbc:mysql:///数据库名 当时本机的时候就可以这么写
try {
conn = DriverManager.getConnection("jdbc:mysql:///test","root","root");
String sql = "update person set money=money+? where uname=?";
//获取预处理器
pst = conn.prepareStatement(sql);
pst.setObject(1, -money);
pst.setObject(2, from);
int result = pst.executeUpdate();
System.out.println(result);
//执行sql
pst.setObject(1, money);
pst.setObject(2, to);
result = pst.executeUpdate();
System.out.println(result);
//得到结果
} catch (SQLException e) {
e.printStackTrace();
}finally {
//关闭资源
if(pst != null) {
try {
pst.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
函数中三个参数分别是from转账人,to收款人,money转账金额
思路也非常的简单,转账人的金额减少,收款人的金额增加。
比如开始的时候数据如下:

一次执行完毕后:

但是这时候就有一个问题:
这里我就把所有的代码都贴上来把我在第一个人的钱减少之后插入如下的代码段:
String s = null;
s.toString();
程序执行完毕可以看到报了一个空指针异常:

上面原来的数据是8000和2100所以总共是10100
但是现在数据如下:

所以a的那1000块钱去哪里了,如果你是a客户,你会乐意吗。哇太棒了今天系统吃了我1000块好开心。
这时候就要用到事务的回滚了,再次将代码修改如下:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* @author Hercules
* @version 创建时间:2020年6月12日 下午7:43:49
* 类说明
*/
public class Money {
public static void main(String[] args) {
money("a", "b", 1000);
}
public static void money(String from,String to,double money) {
//加载驱动
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//获取连接
Connection conn = null;
PreparedStatement pst = null;
//jdbc:mysql://主机地址:端口/数据库名
//jdbc:mysql:///数据库名 当时本机的时候就可以这么写
try {
conn = DriverManager.getConnection("jdbc:mysql:///test","root","root");
conn.setAutoCommit(false);//将自动的事务提交设置为false
String sql = "update person set money=money+? where uname=?";
//获取预处理器
pst = conn.prepareStatement(sql);
pst.setObject(1, -money);
pst.setObject(2, from);
int result = pst.executeUpdate();
System.out.println(result);
//执行sql
String s = null;
s.toString();
pst.setObject(1, money);
pst.setObject(2, to);
result = pst.executeUpdate();
System.out.println(result);
//得到结果
//提交事务
conn.commit();
} catch (Exception e) {
try {
conn.rollback();//如果跑出了异常就让事务回滚
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}finally {
//关闭资源
if(pst != null) {
try {
pst.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
事务回滚就是只要发生了异常,就会将原本的操作数据的步骤逆向还原。这里再来执行一次:可以看到这里还是捕获了异常

下面刷新数据库:

但是数据库还是保持着原本的数据没有变
所以事务回滚的基本操作如下:
首先需要将事务自动提交设置成false
conn.setAutoCommit(false);//将自动的事务提交设置成false
如果抛出异常需要在对应的catch中捕获异常 回滚事务
try {
//如果抛出了异常就让事务回滚
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
如果正确执行完成需要提交事务(如果事务没有提交,数据库也不会改变)
conn.commit();//提交事务

被折叠的 条评论
为什么被折叠?



