美文网首页
JDBC(四)事务管理

JDBC(四)事务管理

作者: 贾里 | 来源:发表于2017-08-16 20:31 被阅读21次

1.银行转账案例

案例:银行转账:从张无忌账户上给赵敏转1000块钱.
准备:account(账户表):

id            name(账号,唯一)           balance(余额)
1             张无忌                    20000
2             赵敏                      0

转账操作步骤:
①:查询张无忌的账户余额是否大于等于1000.

SELECT * FROM account WHERE  name = '王健林' AND balance >= 100;

余额小于1000 : 温馨提示:亲,你的余额不足.
余额大于等于1000: GOTO 2;
②:从王健林的账户余额中减少100.

UPDATE account SET balance = balance - 1000 WHERE name = '王健林';

③:在马云的账户余额中增加100.

UPDATE account SET balance = balance + 1000 WHERE name = '马云';
public class TransactionTest extends TestCase {

    // 案例:银行转账:从王健林账户上转100个亿给马云
    public void testTranscation() throws Exception {

        // 1.查询王健林账户的余额是否大约100亿
        String sql = "SELECT * FROM t_account WHERE name =? AND balance >= ?";
        Connection conn = JdbcUtil.getConn();
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setString(1, "王健林");
        ps.setInt(2, 2000);
        ResultSet rs = ps.executeQuery();
        int wBalance = 0;
        if (rs.next()) {
            wBalance = rs.getInt("balance");
            System.out.println(rs.getString("name") + "还有" + wBalance + "的余额");
        } else {
            throw new RuntimeException("余额不足");
        }

        // 2.从王健林的账户中余额减少100
        sql = "UPDATE t_account SET balance= ? WHERE name= ?";
        ps = conn.prepareStatement(sql);
        ps.setInt(1, wBalance - 100);
        ps.setString(2, "王健林");
        ps.executeUpdate();

        // 3.查询马云的余额
        int mBalance = 0;
        sql = "SELECT * FROM t_account WHERE name =?";
        ps = conn.prepareStatement(sql);
        ps.setString(1, "马云");
        rs = ps.executeQuery();
        if (rs.next()) {
            mBalance = rs.getInt("balance");
            System.out.println(rs.getString("name") + "还有" + mBalance + "的余额");
        } else {
            throw new RuntimeException("没有马云账户");
        }

        // 4.给马云的账户余额中增加100
        sql = "UPDATE t_account SET balance= ? WHERE name= ?";
        ps = conn.prepareStatement(sql);
        ps.setInt(1, mBalance + 100);
        ps.setString(2, "马云");
        ps.executeUpdate();

        // 关闭资源
        JdbcUtil.close(conn, ps, rs);
    }

}

悲剧的事情来了:当程序执行到第②步和第③步之间,突然停电了.
使用异常来模拟停电:System.out.println(1/0);


2.JDBC的事务操作

事务(Transaction,简写为tx):

  • 在数据库中,所谓事务是指一组逻辑操作单元,使数据从一种状态变换到另一种状态。

  • 为确保数据库中数据的一致性,数据的操纵应当是离散的成组的逻辑单元:
    (1)当每个逻辑操作单元全部完成时,数据的一致性可以保持;
    (2)而当这个单元中的一部分操作失败,整个事务应全部视为错误,所有从起始点以后的操作应全部回退到开始状态。

  • 事务的操作:先定义开始一个事务,然后对数据作修改操作,这时如果提交(commit),这些修改就永久地保存下来,如果回退(rollback),数据库管理系统将放弃您所作的所有修改而回到开始事务时的状态。

  • 事务:指构成单个逻辑工作单元的操作集合。

  • 事务处理:保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的事务都被提交(commit),要么整个事务回滚(rollback)到最初状态。

简单讲:事务其实就是多个操作,把多个操作看成是一个不可分割的整体,整体中的多个要成功都成功,要失败都失败。
在红楼梦中: 一损俱损,就是这个思想.


事务的ACID属性:

1. 原子性(Atomicity):原子在化学中,是最小单位,不可以再分割了。
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
2. 一致性(Consistency):包装数据的完整性。
事务必须使数据库从一个一致性状态变换到另外一个一致性状态。(数据不被破坏)
3. 隔离性(Isolation):事务的隔离性是指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
4. 持久性(Durability):
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响。


事务的操作:

事务成功: 提交事务(commit),如果事务不提交,在数据库中数据永远都不会改变;
事务失败: 出现异常的时候,事务失败.事务回滚:rollback(取消之前所有的操作,回到事务最初的状态),释放锁资源。


操作事务的模板:

try{
    取消事务的自动提交机制,设置为手动提交. connection对象.setAutoCommit(false);
    操作1
    操作2
    异常
    操作3
    ....
   手动提交事务                          connection对象.commit();
}catch(Exception e){
   //处理异常
   回滚事务                              connection对象.rollback();
}

上面案例的事务处理

public void testTranscation() {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtil.getConn();
            conn.setAutoCommit(false);// 取消事务的自动提交机制
            String sql = "SELECT * FROM t_account WHERE name =? AND balance >= ?";
            ps = conn.prepareStatement(sql);
            ps.setString(1, "王健林");
            ps.setInt(2, 2000);
            rs = ps.executeQuery();
            int wBalance = 0;
            if (rs.next()) {
                wBalance = rs.getInt("balance");
                System.out.println(rs.getString("name") + "还有" + wBalance + "的余额");
            } else {
                throw new RuntimeException("余额不足");
            }
            // 2.从王健林的账户中余额减少100
            sql = "UPDATE t_account SET balance= ? WHERE name= ?";
            ps = conn.prepareStatement(sql);
            ps.setInt(1, wBalance - 100);
            ps.setString(2, "王健林");
            ps.executeUpdate();

            // 3.查询马云的余额
            int mBalance = 0;
            sql = "SELECT * FROM t_account WHERE name =?";
            ps = conn.prepareStatement(sql);
            ps.setString(1, "马云");
            rs = ps.executeQuery();
            if (rs.next()) {
                mBalance = rs.getInt("balance");
                System.out.println(rs.getString("name") + "还有" + mBalance + "的余额");
            } else {
                throw new RuntimeException("没有马云账户");
            }
            System.out.println(1 / 0); // 模拟停电
            // 4.给马云的账户余额中增加100
            sql = "UPDATE t_account SET balance= ? WHERE name= ?";
            ps = conn.prepareStatement(sql);
            ps.setInt(1, mBalance + 100);
            ps.setString(2, "马云");
            ps.executeUpdate();
            conn.commit();//提交事务
            System.out.println("转账成功");
        } catch (Exception e) {
            try {
                conn.rollback();   //事务回滚
                System.out.println("转账失败");
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        } finally {
            // 关闭资源
            JdbcUtil.close(conn, ps, rs);
        }

    }

事务相关的:

  • 1.默认情况下,事务在执行完DML操作就自动提交.
  • 2.查询操作,其实是不需要事务的.但是,一般的,我们在开发中都把查询放入事务中.
  • 3.开发中,代码完全正确,没有异常,但是就是数据库中数据不变.
    意识:没有提交事务.
  • 4.在MySQL中,只有InnoDB存储引擎支持事务,支持外键,MyISAM不支持事务.
  • 5.以后事务我们不应该在DAO层处理,应该在service层控制.
  • 6.事务在讲解Hibernate,MyBatis,Spring,项目的时候都会再讲.

相关文章

  • JDBC(四)事务管理

    1.银行转账案例 案例:银行转账:从张无忌账户上给赵敏转1000块钱.准备:account(账户表): 转账操作步...

  • jdbc存储过程

    jdbc事务管理 数据库连接池

  • Spring事务

    容器事务 Spring事务核心接口 JDBC事务管理器(DataSourceTransactionManager)...

  • Spring 事务管理相关知识

    一、事务管理 1. 几种事务 JDBC事务 Hibernate事务 2. Spring 事务管理 产生的原因和一些...

  • JDBC:Java数据库连接

    JDBC常用接口 JDBC编程步骤 执行SQL语句 管理结果集 事务管理 高级应用:分页、高级查询、高级函数使用

  • NO.52 JDBC高级编程、DAO

    一.JDBC中的事务管理 1.自动管理事务 JDBC会自动管理事务 每次调用executeUpdate()时,它会...

  • 第二章1.0初识Spring

    JDBC Template --使用了 模板模式ORM --使用了策略模式 Transaction 事务管理 ...

  • [二]事务原则与实现

    导航 一. 事务的原则 二. SQL实现数据库事务管理 三. JDBC实现事务管理 一. 事务的原则 事务的描述事...

  • spring事务管理

    1. 事务管理的基本原理 spring事务管理实际上数据库对事务的支持,在java中使用的是JDBC的事务管理机制...

  • jdbc事务管理

网友评论

      本文标题:JDBC(四)事务管理

      本文链接:https://www.haomeiwen.com/subject/bfkprxtx.html