基本事务理念

90 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第27天,点击查看活动详情

01.事务_概念:

1).什么是"事务" : 事务,是数据库中的概念,它是指程序的一个"业务"在数据库中要由多个SQL语句完成,例如:

转账业务:张三给李四转账1000元:

数据库中:

  • 张三账户减少1000元;
  • 李四账户增加1000元;

如果在执行第一条语句之后,系统崩溃,或者断电,将会导致张三账户减少1000元而李四账户没有增加, 就会导致数据错误。对于这种情况,要求数据库软件必须要有能力,将这些SQL语句看成是一个"整体", 执行后,要么全部成功,要么全部失败。这种操作能力就叫:事务处理。

02.事务_MySQL中处理事务的方式:

1).MySQL中默认的事务处理方式:自动提交(自动事务)。它将每条SQL语句都作为一个独立的事务执行,执行后,立即修改数据库,数据会被永久修改。语句和语句之间没有任何关联。这种方式不能满足我们业务的需求;

2).查看MySQL中的事务处理方式:

show variables like 'autocommit';
查询结果:
autocommit    ON (自动提交--开启)    

3).MySQL中处理事务的方式:

1).关闭自动提交,设置为手动提交:(只对当前登录用户有效)
    1).关闭自动提交
        set autocommit = off;
    2).发送SQL语句:
        update ....
        insert ....
        delete ....
    3).提交
            commit;
       回滚
        rollback;
2).在自动提交状态下,开启一个临时事务:【重点掌握】
    1).开启临时事务:
        start transaction;
    2).发送SQL语句:
        update ...
        insert ...
        delete ...
    3).提交
        commit;    //会立即结束本次事务,恢复到自动提交状态
       回滚
        rollback;//会立即结束本次事务,恢复到自动提交状态

03.事务_JDBC中处理事务的方式:

.....
//关闭自动提交
conn.setAutoCommit(false);
.....

try{
    //4.发送SQL语句
    ......
    //提交
    conn.commit();
}catch(Exception e){
    //回滚
    conn.rollback();
}
.....

04.事务_DBUtils中处理事务的方式:

//1.创建一个QueryRunner对象
QueryRunner qr = new QueryRunner();//如果要使用事务处理,这里就不需要连接池构造
//2.从连接池获取一个Connection对象
Connection conn = DataSourceUtils.getConnection();
//3.关闭自动提交
conn.setAutoCommit(false);
//4.执行查询
try{
    int row1 = qr.update(conn, "update account set balance = balance - 1000 where uname = 'zhangsan'");
    int row2 = qr.update(conn, "update account set balance = balance + 1000 where uname = 'lisi'");
    if(row1 == 0 || row2 == 0){
        throw new Exception();
    }
    //提交
    conn.commit();
    System.out.println("提交......");
}catch(Exception e){
    //回滚
    conn.rollback();
    System.out.println("回滚...");
}

//5.恢复为自动提交
conn.setAutoCommit(true);
//6.归还连接
conn.close();

05.事务的特性【了解】:

1).事务的特性:

原子性:强调事务的不可分割.多条语句要么都成功,要么都失败。
一致性:强调的是事务的执行的前后,数据要保持一致.
隔离性:一个事务的执行不应该受到其他事务的干扰.
持久性:事务一旦结束(提交/回滚)数据就持久保持到了数据库.

2).如果两个事务不隔离,可能产生的情况:

脏读:一个事务读到另一个事务还没有提交的数据.
不可重复读:一个事务读到了另一个事务已经提交的update的数据,导致在当前的事务中多次查询结果不一致.
虚读/幻读:一个事务读到另一个事务已经提交的insert的数据,导致在当前的事务中多次的查询结果不一致.

3).四个隔离级别:

1 read uncommitted:未提交读.脏读,不可重复读,虚读都可能发生.
2 read committed:已提交读.避免脏读.但是不可重复读和虚读有可能发生.(Oracle默认)
4 repeatable read:可重复读.避免脏读,不可重复读.但是虚读有可能发生.(MySql默认)
8 serializable:串行化的.避免脏读,不可重复读,虚读的发生.

4).查看当前的隔离级别:

select @@tx_isolation;

5).设置当前会话的隔离级别:

set session transaction isolation level 上述四个隔离级别之一;