序号 | 特性 | 描述 |
---|---|---|
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) | 在当前事务中创建一个保存点 |
package com.rk.db.g_transaction; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import com.rk.db.utils.JDBCUtil; /** * // 转账,使用事务 * @author RK * */ 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); } } /** * 模拟银行转账 * @param conn 数据库连接 * @param moneyNum 转账的金额 * @param userAdd 收到Money的用户 * @param userSub 支出Money的用户 * @param flag 是否模拟SQL Exception异常,true表示出现,false表示不出现 * @throws SQLException */ 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); } } }
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; /** * // 转账,使用事务, 回滚到指定的代码段 * @author RK * */ 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); } } /** * 模拟银行转账 * @param conn 数据库连接 * @param moneyNum 转账的金额 * @param userAdd 收到Money的用户 * @param userSub 支出Money的用户 * @param flag 是否模拟SQL Exception异常,true表示出现,false表示不出现 * @throws SQLException */ 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); } } }
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。