zoukankan      html  css  js  c++  java
  • mysql事物处理

    mysql事物主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你既要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等。这样,这些数据库操作语句就构成一个事物。注意一下几点:

    • 在MySQL中只有使用了Innodb数据库引擎的数据库或表才支持事务。
    • 事物处理可以用来维护数据库的完整性,保证成批的sql语句要么全部执行,要么全部不执行。
    • 事物用来管理insert,update,delete语句。

    先简单介绍一下事物吧。事物是DBMS的执行单位。它由有限的数据库操作序列组成的,但不是任意的数据库操作序列都能成为事物。一般来说,事物必须满足4个条件(ACID):

    原子性:组成事物处理的语句形成了一个逻辑单元,不能只执行其中一部分。换句话说,事物是不可分割的最小单元。比如银行转账过程中,必须同时从一个账户减去转账金额,并加到另一个账户中,只改变一个账户是不合理的。

    一致性:在事物处理执行前后,mysql数据库是一致的。也就是说,事物应该正确的转换系统状态。比如银行转账过程中,要么转账金额从一个账户到另一个账户,要么两个账户都不变,没有其他情况。

    隔离性:一个事物处理对另外一个事物处理没有影响。比如说银行转账过程中,在转账事物没有提交之前,另一个转账事物只能处于等待状态 。

    可靠性:事物处理的效果能够被永久保存下来。反过来说,事物能够承受所有的失败。包括服务器,进程,通信以及媒体失败等等。比如银行转账过程中,转账后账户的状态要能被保存下来。

      mysql的事物处理主要有两种方法:

    1. begin,rollback,commit来实现

    begin 开始一个事物

    rollback 事物回滚

    commit 事物确认,事物提交

    2,直接用set来改变mysql的自动提交模式

    mysql默认z是自动提交的,也就是你提交一个query,它就直接执行。

    set autocommit = 0 禁止自动提交模式

    set autocommit = 1 开启自动提交模式

     

      mysql中只用INNODB和BDB类型的数据表才能支持事物处理(切记)!

    来看一个例子:

    先假设一下问题的背景:网上购书,某书《mysql数据库》编号为123,只剩最后一本,而这个时候两个用户几乎同时对这本书发出了购书请求,让我们来看看整个过程:

    在具体分析之前,先来看看数据表的定义:

     

      对于用户甲来说,他的动作稍微比乙快一点点,其购买过程中所触发的动作大致是这样的:

    1.select book_number from book where book_id = 123;

    book_number 大于0,确认购买行为并更新book_number 

    2.update book set book_number = book_number—1 where book_id = 123; 

      购书成功

    表面上看甲乙的操作都成功了,他们都买到了书,但是库存只有一本,他们怎么可能都成功呢?再看看数据表里book_number的内容,已经变成“-1”了,这当然是不能允许的(实际上,声明这样的列类型应该加上unsigned的属性,以保证其不能为负,这里是为了说明问题所以没有这样设置) 

      好了,问题陈述清楚了,再来看看怎么利用事务来解决这个问题,打开MySQL手册,可以看到想用事务来保护你的SQL正确执行其实很简单,基本就是三个语句:开始,提交,回滚。

    开始:START TRANSACTION或BEGIN语句可以开始一项新的事务

    提交:COMMIT可以提交当前事务,是变更成为永久变更

    回滚:ROLLBACK可以回滚当前事务,取消其变更

    此外,SET AUTOCOMMIT = {0 | 1}可以禁用或启用默认的autocommit模式,用于当前连接。

    那是不是只要用事务语句包一下我们的SQL语句就能保证正确了呢?比如下面代码: 

     

      答案是否定了,这样依然不能避免问题的发生,如果想避免这样的情况,实际应该如下:

     

      由于加入了FOR UPDATE,所以会在此条记录上加上一个行锁,如果此事务没有完全结束,那么其他的事务在使用SELECT ... FOR UPDATE请求的时候就会处于等待状态,直到上一个事务结束,它才能继续,从而避免了问题的发生,需要注意的是,如果你其他的事务使用的是不带FOR UPDATE的SELECT语句,将得不到这种保护。

  • 相关阅读:
    docker-compose写法收集
    【CodeForces】704 C. Black Widow 动态规划+模拟
    【BZOJ】2693: jzptab 莫比乌斯反演
    【BZOJ】2154: Crash的数字表格 莫比乌斯反演
    【CodeForces】915 G. Coprime Arrays 莫比乌斯反演
    【CodeForces】915 F. Imbalance Value of a Tree 并查集
    【CodeForces】915 E. Physical Education Lessons 线段树
    【CodeForces】915 D. Almost Acyclic Graph 拓扑排序找环
    【Atcoder】AGC 020 B
    【Atcoder】AGC 020 D
  • 原文地址:https://www.cnblogs.com/leijiangtao/p/4524821.html
Copyright © 2011-2022 走看看