首页 > 代码库 > 12.关于mysql事物。

12.关于mysql事物。

一、什么是事物?

个人理解,sql中的事物就是给sql语句做一个分组,组内的sql语句要不然就全部执行成功,要不然就完全的不会执。或者说作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。

 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。一个逻辑工作单元要成为事务。


二、关于事物的示例,以及如何在mysql中开启事物。

start transaction;开启事务

Rollback 回滚事务,即撤销指定的sql语句(只能回退insert delete update语句),回滚到上一次commit的位置.

Commit 提交事务,提交未存储的事务.

savepoint 保留点 ,事务处理中设置的临时占位符 你可以对它发布回退(与整个事务回退不同).(也可以理解为回退到某个点,并不会完全回退到上次commit的位置。)


示例:

create table test2(id int PRIMARY KEY auto_increment,name VARCHAR(20)) engine=innodb;

INSERT INTO test2(name) VALUE ("user1"),("user2"),("user3");


start transaction; #创建事物。

insert into test2 (name)values(‘user4‘);

select * from test2;

commit; #提交后,真正的把数据写到数据库中。

-------------------------下面是关于保留点的示例-------------------------------

start transaction;

insert into test2 (name)values(‘wu‘);

savepoint insert_wu; #定义一个保留点

select * from test2;

delete from test2 where id=4;

savepoint delete1; #定义一个保留点

select * from test2;

delete from test2 where id=1;

savepoint delete2; #定义一个保留点

select * from test2;

rollback to delete1;  #回滚到哪个保留点之后。

select * from test2;


python中调用数据库启动事务的方式:

import pymysql

#添加数据

conn = pymysql.connect(host=‘127.0.0.1‘, port=3306, user=‘root‘, passwd=‘‘, db=‘yyy‘)

cursor = conn.cursor()

try:

    insertSQL0="INSERT INTO ACCOUNT2 (name,balance) VALUES (‘user1‘,4000)"

    insertSQL1="UPDATE account2 set balance=balance-30 WHERE name=‘user2‘"

    insertSQL2="UPDATE account2 set balance=balance+30 WHERE name=‘user3"

    cursor = conn.cursor()

    cursor.execute(insertSQL0)

    conn.commit()

    cursor.execute(insertSQL1)

    raise Exception   #触发异常,用来模拟第三条sql语句执行异常。

    cursor.execute(insertSQL2)

    cursor.close()

    conn.commit()

except Exception as e:

    conn.rollback()

    conn.commit()

cursor.close()

conn.close()


三、事物特性的总结:

  1. 原子性:

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

  2. 隔离性:

    事务的隔离性是指多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。

  3. 永久性:

    事物一旦被提交,它对数据库中数据的改变就是永久性的。


事物的隔离性是非常重要的!!如果不考虑隔离性会出现以下问题。

  1. 脏读(读取脏数据)

    脏读就是一个事物读取到了另外一个事物还没有提交的数据,这种情况在生产环境特别危险!!

    假如说,现在事物1正在修改某一个数据,并且准备提交(还没有提交!),此时,事物2读取到了同一数据之后,事物1由于执行了某条sql语句没成功,突然回滚,此时的事物1已经把修改过的数据,变回了原来的值,事物2所读到的,是事物1之前修改过还没提交的数据,所以说,事物2所读到的数据和数据库中的数据根本不一致!!所以是不正确的数据。

    关于脏读的示例:


            a 1000

            b 1000

            a:

                start transaction;

                update set money=money+100 where name=b;

            b:

                start transaction;

                select * from account where name=b;--1100

                commit;

            a:

                rollback;

            b:  start transaction;

                select * from account where name=b;--1000


  2.不可重复读:

    事物1读取了数据库中的数据后,事物2对这个数据进行了更新操作,导致事物1无法读取前一次的结果。

说的再简单一些,就是在一个事物内读取表中的某一行记录,多次读取的内容是不同的。

事务1读取某一数据后,事物2对其做了修改,当事物1再次读该数据后,得到与前一不同的值。


3.产生幽灵数据:

是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。(一个事务读取到了另一个事务已经提交的数据—增加记录、删除记录),在某写情况下并不是问题,在另一些情况下就是问题。

b 1000

c 2000

d 3000

a:

start transaction

select sum(money) from account;---3000       3000

-------------------

d:start transaction;

insert into account values(d,3000);

commit;

-------------------

select count(*)from account;---3                         3

3000/3 = 1000                                            1000   


避免以上几种情况发生的隔离级别:

四个隔离级别:

Serializable:可避免脏读、不可重复读、虚读情况的发生。(串行化)

Repeatable read:可避免脏读、不可重复读情况的发生。(可重复读)不可以避免虚读

Read committed:可避免脏读情况发生(读已提交)

Read uncommitted:最低级别,以上情况均无法保证。(读未提交)

安全性考虑:Serializable>Repeatable read>Read committed>Read uncommitted

数据库效率:Read uncommitted>Read committed>Repeatable read>Serializable

一般情况下,我们会使用Repeatable read、Read committed mysql数据库默认的数据库隔离级别Repeatable read


mysql中设置数据库的隔离级别语句:

set [global/session] transaction isolation level xxxx;

如果使用global则修改的是数据库的默认隔离级别,所有新开的窗口的隔离级别继承自这个默认隔离级别如果使用session修改,则修改的是当前客户端的隔离级别,和数据库默认隔离级别无关。当前的客户端是什么隔离级别,就能防止什么隔离级别问题,和其他客户端是什么隔离级别无关。

mysql中设置数据库的隔离级别语句:


select @@tx_isolation;


本文出自 “reBiRTH” 博客,请务必保留此出处http://suhaozhi.blog.51cto.com/7272298/1934310

12.关于mysql事物。