事务的学习

117 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情

一.事务的概念:

一组逻辑操作单元,时数据从一个状态转换到另一个状态。

二.事务处理的原则:

保证所有的事务都被当做一个操作单元来执行,即使出现了故障,也不能改变这种处置原则。要么与事务相关的数据全部被修改,并永远的提交保存下来,要么所有的事务全部回滚到事务没被执行的状态。

三.那些操作会影响数据库的提交

(一).数据库连接一旦断开,数据库的数据都被会提交

(二).DDL操作完成,数据自动提交,并且无法回滚

(三).DML操作默认为提交,但是可以通过 set auto commit = false;来设置不允许自动提交

四.模拟事务提交

事务执行过程图:

image.png 通用的包含事务的更新方法

/**
 * 包含事务的通行的方法实现增删改
 * @param conn 从外部传入的数据库连接,意图在执行完一次DML操作时,数据库的连接不会断开,
 *             确保事务不会因为连接断而出现提交的现象
 * @param sql 增删改语句
 * @param args 占位符?个数不一定,根据sql占位符的个数,传入对应数量object
 */
public static int update(Connection conn,String sql,Object... args){
    int temp = -1;
    PreparedStatement pst = null;
    try{
        //2.预编译sql语句
        pst = conn.prepareStatement(sql);
        //3.填充占位符
        for (int i = 0; i < args.length; i++) {
            pst.setObject(i+1,args[i]);
        }
        //4.执行
        /*
        pst.execute();如果是查询操作返回的是true
                        如果是更新操作返回的是false;
        pst.executeUpdate();返回执行操作以后受影响的行数
         */
             pst.execute();
        temp = pst.executeUpdate();
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        //5.释放资源
        closeResource(null,pst);
    }
    return temp;
}

(一).模拟存在异常情况下的102给103转账100元操作;

image.png 转账失败

image.png

image.png

(二).模拟不存在异常下转账的情况

image.png 转账成功

image.png

image.png

五.事务的ACID属性

(一).事务的属性

1.原子性:

原子性是指事务时一个不可分割的工作单元,事务中的操作要么都发生,要么都不发生

2.一致性:

事务必须使数据库从一个一致状态转换到另一个一致状态

3.隔离性:

事务并发在执行时,各个事务之间的数据互不干扰的,各个事务 之间的数据不受任何影响

4.持久性:

事务一旦被提交,就是永久性的改变,接下来发生的事或数据库故障都不会对其有任何我影响。

(二).事务的并发问题

1.脏读:

    读出了未提交的数据。事务T1,事务T2,T1读入一个数据段A,读出值为1,此时T2修改了A的值,T1将A= 2的值读出,但此时T2撤销了事务,回滚到A=1的阶段。此时T1读出的数据无效,即为脏读:

2.不可重复读:

    只读提交的数据,并且第一次读出来是什么,在提交之前,读出来的东西和第一次保持一致;事务T1在第一次读到A=1,在读到以后,无论其他事务(T2)对字段A怎么更新提交(A=2),T1在提交前读出A字段永远都是A=1

3.幻读:

事务T1第一次读出100条数据,T2插入3条数据并提交,T1提交后,T1再次读,读出103条数去,即为幻读,