JDBC系列:(7)使用Connection操作事务
短信预约 -IT技能 免费直播动态提醒
序号 | 特性 | 描述 |
---|---|---|
1 | 原子性(Atomicity) | 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。 |
2 | 一致性(Consistency) | 事务必须使数据库从一个一致性状态变换到另外一个一致性状态。 |
3 | 隔离性(Isolation) | 事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。 |
4 | 持久性(Durability) | 持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响 |
序号 | 方法 | 作用 |
---|---|---|
1 | void setAutoCommit(boolean autoCommit) | 设置事务是否自动提交 如果设置为false,表示手动提交事务。 |
2 | void commit() () | 手动提交事务 |
3 | void rollback() | 回滚(出现异常时候,所有已经执行成功的代码需要回退到事务开始前的状态。) |
4 | Savepoint setSavepoint(String name) | 在当前事务中创建一个保存点 |
1、使用事务
package com.rk.db.g_transaction;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import com.rk.db.utils.JDBCUtil;
public class Demo01
{
public static void main(String[] args)
{
Connection conn = null;
try
{
conn = JDBCUtil.getConnection();
// 1、设置事务为手动提交
conn.setAutoCommit(false);
boolean flag = true; //表示是否出现SQL异常
transferMoney(conn, 100, "张三", "李四",flag);
}
catch (SQLException e)
{
System.out.println("转账失败!");
try
{
// 2、 出现异常,需要回滚事务
conn.rollback();
System.out.println("回滚操作成功!!!");
}
catch (SQLException ex)
{
ex.printStackTrace();
}
}
finally
{
// 3、所有的操作执行成功, 提交事务
try
{
conn.commit();
System.out.println("执行完毕!");
}
catch (SQLException e)
{
e.printStackTrace();
}
JDBCUtil.closeQuietly(conn);
}
}
private static void transferMoney(Connection conn,
long moneyNum, String userAdd, String userSub,
boolean flag) throws SQLException
{
PreparedStatement pstmtAdd = null;
PreparedStatement pstmtSub = null;
try
{
String sqlAddMoney = "update T_Bank set money=money+? where username=?";
pstmtAdd = conn.prepareStatement(sqlAddMoney);
pstmtAdd.setLong(1, moneyNum);
pstmtAdd.setString(2, userAdd);
pstmtAdd.executeUpdate();
if(flag)
{
throw new SQLException("模拟SQL执行出错");
}
String sqlSubMoney = "update T_Bank set money=money-? where username=?";
pstmtSub = conn.prepareStatement(sqlSubMoney);
pstmtSub.setLong(1, moneyNum);
pstmtSub.setString(2, userSub);
pstmtSub.executeUpdate();
}
finally
{
JDBCUtil.closeQuietly(pstmtAdd);
JDBCUtil.closeQuietly(pstmtSub);
}
}
}
2、使用事务,回滚到指定的代码段
package com.rk.db.g_transaction;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Savepoint;
import com.rk.db.utils.JDBCUtil;
public class Demo02
{
public static void main(String[] args)
{
Connection conn = null;
Savepoint sp = null;
try
{
conn = JDBCUtil.getConnection();
// 1、设置事务为手动提交
conn.setAutoCommit(false);
transferMoney(conn, 1000, "李四", "张三",false);
// 如果失败,回滚到这个位置
sp = conn.setSavepoint();
boolean flag = true; //表示是否出现SQL异常
transferMoney(conn, 500, "张三", "李四",flag);
}
catch (SQLException e)
{
System.out.println("转账失败!");
try
{
// 2、 出现异常,需要回滚 (回滚到指定的代码段)
conn.rollback(sp);
System.out.println("回滚到指定位置操作成功!!!");
}
catch (SQLException ex)
{
ex.printStackTrace();
}
}
finally
{
// 3、所有的操作执行成功, 提交事务
try
{
conn.commit();
System.out.println("执行完毕!");
}
catch (SQLException e)
{
e.printStackTrace();
}
JDBCUtil.closeQuietly(conn);
}
}
private static void transferMoney(Connection conn,
long moneyNum, String userAdd, String userSub,
boolean flag) throws SQLException
{
PreparedStatement pstmtAdd = null;
PreparedStatement pstmtSub = null;
try
{
String sqlAddMoney = "update T_Bank set money=money+? where username=?";
pstmtAdd = conn.prepareStatement(sqlAddMoney);
pstmtAdd.setLong(1, moneyNum);
pstmtAdd.setString(2, userAdd);
pstmtAdd.executeUpdate();
if(flag)
{
throw new SQLException("模拟SQL执行出错");
}
String sqlSubMoney = "update T_Bank set money=money-? where username=?";
pstmtSub = conn.prepareStatement(sqlSubMoney);
pstmtSub.setLong(1, moneyNum);
pstmtSub.setString(2, userSub);
pstmtSub.executeUpdate();
}
finally
{
JDBCUtil.closeQuietly(pstmtAdd);
JDBCUtil.closeQuietly(pstmtSub);
}
}
}
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341