一:事物的隔离级别

1:隔离级别的类型

SQL标准定义了4类隔离级别,包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的;

Read Uncommitted(读取未提交内容)

Read Committed(读取提交内容)

Repeatable Read(可重读)【mysql默认的设置】

Serializable(可串行化)

2:  查看隔离级别

1> 查看当前会话隔离级别:

  select @@tx_isolation;

2> 查看当前系统隔离级别:

  select @@global.tx_isolation;

3:隔离级别的修改

1> 全局修改,修改mysql.ini配置文件,在最后加上

#可选参数有:READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE.
[mysqld]
transaction-isolation = REPEATABLE-READ

2>对当前session修改,在登录mysql客户端后,执行命令:

SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}

4: 不同隔离级别的特性:

1. 脏读 :脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。
 e.g.
        1.Mary的原工资为1000, 财务人员将Mary的工资改为了8000(但未提交事务)
        2.Mary读取自己的工资 ,发现自己的工资变为了8000,欢天喜地!
        3.而财务发现操作有误,回滚了事务,Mary的工资又变为了1000
          像这样,Mary记取的工资数8000是一个脏数据。

2.
不可重复读
:是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的
修改,那么第一个事务两次读到的的数据可能是不一样的。这样在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。
    e.g.
    1.在事务1中,Mary 读取了自己的工资为1000,操作并没有完成
    2.在事务2中,这时财务人员修改了Mary的工资为2000,并提交了事务.
    3.在事务1中,Mary 再次读取自己的工资时,工资变为了2000

解决办法:如果只有在修改事务完全提交之后才可以读取数据,则可以避免该问题。

3.
幻读 :
是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中
的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。
   e.g. 
   目前工资为1000的员工有10人。
   1.事务1,读取所有工资为1000的员工。
   2.这时事务2向employee表插入了一条员工记录,工资也为1000
   3.事务1再次读取所有工资为1000的员工 共读取到了11条记录, 
 
 解决办法:如果在操作事务完成数据处理之前,任何其他事务都不可以添加新数据,则可避免该问题

区别:

不可重复读的重点是修改 :
 同样的条件, 你读取过的数据,再次读取出来发现值不一样了
幻读的重点在于新增或者删除
 同样的条件, 第 1 次和第 2 次读出来的记录数不一样

数据库带来的并发问题包括:

  1.丢失或覆盖更新。(幻像读)

  2.未确认的相关性(脏读)。

  3.不一致的分析(非重复读)。

详细描述如下:

一.丢失更新

当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,会发生丢失更新问题。每个事务都不知道其它事务的存在。最后的更新将重写由其它事务所做的更新,这将导致数据丢失。   

e.g.事务A和事务B同时修改某行的值,

1.事务A将数值改为1并提交

2.事务B将数值改为2并提交。

这时数据的值为2,事务A所做的更新将会丢失。

解决办法:对行加锁,只允许并发一个更新事务。

分布式事务:

分布式事务的参与者、资源管理器、事务管理器等位于不用的节点上,这些不同的节点相互协作共同完成一个具有逻辑完整性的事务。

mysql从5.0开始支持XA DataSource。Connector/J 版本要使用5.0版本,5.0以下的不支持。

分布式事物实现代码:

XA协议由Tuxedo首先提出的,并交给X/Open组织,作为资源管理器(数据库)与事务管理器的接口标准。目前,Oracle、Informix、DB2和Sybase等各大数据库厂家都提供对XA的支持。XA协议采用两阶段提交方式来管理分布式事务。XA接口提供资源管理器与事务管理器之间进行通信的标准接口。XA协议包括两套函数,以xa_开头的及以ax_开头的。

  以下的函数使事务管理器可以对资源管理器进行的操作:
  1)xa_open,xa_close:建立和关闭与资源管理器的连接。
  2)xa_start,xa_end:开始和结束一个本地事务。
  3)xa_prepare,xa_commit,xa_rollback:预提交、提交和回滚一个本地事务。
  4)xa_recover:回滚一个已进行预提交的事务。
  5)ax_开头的函数使资源管理器可以动态地在事务管理器中进行注册,并可以对XID(TRANSACTION IDS)进行操作。
  6)ax_reg,ax_unreg;允许一个资源管理器在一个TMS(TRANSACTION MANAGER SERVER)中动态注册或撤消注册。

MySQL XA分为两类,内部XA与外部XA;内部XA用于同一实例下跨多个引擎的事务,由大家熟悉的Binlog作为协调者;外部XA用于跨多MySQL实例的分
布式事务,需要应用层介入作为协调者(崩溃时的悬挂事务,全局提交还是回滚,需要由应用层决定,对应用层的实现要求较高);

 Binlog作为内部XA的协调者,在binlog中出现的内部xid,在crash
recover时,由binlog负责提交。(这是因为,binlog不进行prepare,
只进行commit,因此在binlog中出现的内部xid,一定能够保证其在底层各存储引擎中已经完成prepare)。

MySQL数据库外部XA可以用在分布式数据库代理层,实现对MySQL数据库的分布式事务支持,例如开源的代理工具:网易的DDB,淘宝的TDDL,B2B的Cobar等等。

示例

public function testAction(){
        $goods_id=1;
        $goods_name = "大西瓜";
        $num = 1;
        $rs_order = $this->test->createorder($goods_id,$goods_name,$num);
        $rs_goods = $this->test->deduction($goods_id,$num);
        if($rs_order['status'] =="success" && $rs_goods['status']=="success"){
            $this->test->commitdb($rs_order['XA']);
            $this->test->commitdb1($rs_goods['XA']);
        }else{
            $this->test->rollbackdb($rs_order['XA']);
            $this->test->rollbackdb1($rs_goods['XA']);
        }
       
        print_r($rs_order);
        echo "<br />";
        print_r($rs_goods);
        die("dddd");
    }
   
    public function createorder($goods_id,$goods_name,$num){
        $XA = uniqid("");
        $this->_db->query("XA START '$XA'");
        $_rs = true;
        try {
            $data = array();
            $data['order_id'] = "V".date("YmdHis");
            $data['goods_name'] = $goods_name;
            $data['goods_num'] = $num;
            $this->_db->insert("temp_orders",$data);
            $rs =  $this->_db->lastInsertId();
            if($rs){
                $_rs = true;
            }else{
                $_rs = false;
            }
        } catch (Exception $e) {
            $_rs = false;
        }
        $this->_db->query("XA END '$XA'");
         if($_rs){
                 $this->_db->query("XA PREPARE '$XA'");
                 return array("status"=>"success","XA"=>$XA);
         }else{
                 return array("status"=>"nosuccess","XA"=>$XA);
         }
    }
   
    public function deduction($id){
        $XA = uniqid("");
        $this->db1->query("XA START '$XA'");
        $last_rs = true;
        try {
                $sql = "select * from temp_goods where id = '$id' and goods_num>0";
                $rs = $this->db1->fetchRow($sql);
                if(!empty($rs)){
                    $sql = "update temp_goods set goods_num = goods_num-1 where id = '$id'";
                    $rd = $this->db1->query($sql);
                    if($rd){
                        $last_rs = true;
                    }else{
                        $last_rs = false;
                    }
                }else{
                        $last_rs = false;;
                }
        } catch (Exception $e) {
             $last_rs = false;;
        }
         $this->db1->query("XA END '$XA'");
         
         if($last_rs){
                 $this->db1->query("XA PREPARE '$XA'");
                 return array("status"=>"success","XA"=>$XA);
         }else{
                 return array("status"=>"nosuccess","XA"=>$XA);
         }
   
    }
    //提交事务!
    public function commitdb($xa){
        return $this->_db->query("XA COMMIT '$xa'");
    }
   
    //回滚事务
    public function rollbackdb($xa){
        return $this->_db->query("XA ROLLBACK '$xa'");
    }
   
    //提交事务!
    public function commitdb1($xa){
        return $this->db1->query("XA COMMIT '$xa'");
    }
   
    //回滚事务
    public function rollbackdb1($xa){
        return $this->db1->query("XA ROLLBACK '$xa'");
    }

php分享十三:mysql事物的更多相关文章

  1. 分享一个MySQL分库分表备份脚本(原)

    分享一个MySQL分库备份脚本(原) 开发思路: 1.路径:规定备份到什么位置,把路径(先判断是否存在,不存在创建一个目录)先定义好,我的路径:/mysql/backup,每个备份用压缩提升效率,带上 ...

  2. mysql事物处理

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

  3. 干货分享:MySQL之化险为夷的【钻石】抢购风暴【转载】

    转自: 干货分享:MySQL之化险为夷的[钻石]抢购风暴 - Vanos_韩尛哲 - 博客园http://www.cnblogs.com/Vanos-lcp/p/5642097.html 抢购钻石不稀 ...

  4. 老李分享:MySql的insert语句的性能优化方案

    老李分享:MySql的insert语句的性能优化方案   性能优化一直是测试人员比较感兴趣的内容,poptest在培训学员的时候也加大了性能测试调优的方面的内容,而性能优化需要经验的积累,经验的积累依 ...

  5. 性能调优案例分享:Mysql的cpu过高

    性能调优案例分享:Mysql的cpu过高   问题:一个系统,Mysql数据库,数据量变大之后.mysql的cpu占用率很高,一个测试端访问服务器时mysql的cpu占用率为15% ,6个测试端连服务 ...

  6. MySQL事物机制具备四点:简称ACID操作

    MySQL事物机制具备四点:简称ACID操作 1.原子性:要么都做,要么都不做(两条数据(写入和存储)一步未成功,整体回滚) 2.一致性:数据库的状态改变(两条数据(写入和存储)均成功,符合原子性,但 ...

  7. php与mysql事物处理

    PHP与MYSQL事务处理 mysql事物特性 (原子性,一致性,隔离性,持久性) /*MYSQL的事务处理主要有两种方法.1.用begin,rollback,commit来实现begin 开始一个事 ...

  8. 小白老凯,初出茅庐!请多关照!简单分享一些 mysql 数据库的安装操作!请给为大神雅正!

    在我们写代码,存储数据时常常会用到各种数据库,如:mysql.access.sql.server.Oracle等等,在这里就说一下mysql数据库的的操作指令! 首先我们了解下如何安装mysql数据库 ...

  9. 实验十三 MySQL多用户事务管理

    实验十三 MySQL多用户事务管理 一.  实验内容: 1. 事务机制的使用 2. 锁机制的使用 二.  实验项目:员工管理数据库 用于企业管理的员工管理数据库,数据库名为YGGL中,YGGL数据库中 ...

  10. MySQL事物原理及事务隔离级别

    mysql事物 事务是访问数据库的一个操作序列,数据库应用系统通过事务集来完成对数据库的存取.事务的正确执行使得数据库从一种状态转换为另一种状态. 事务必须服从ISO/IEC所制定的ACID原则.AC ...

随机推荐

  1. Percona-XtraBackup系列一:安装 perl(Time::HiRes) is needed by percona-xtrabackup-2.2.10-1.el6.x86_64

    1:在percona官网下载最新的Xtrabackup http://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.2.10/bi ...

  2. Java同步机制之Monitor监视器与syncrhoized实现原理

    转载请注意原文地址:http://www.cnblogs.com/ygj0930/p/6561667.html  一:Monitor Monitor是一个同步工具,相当于操作系统中的互斥量(mutex ...

  3. 如何捕获 System.loadLibrary 产生的异常?(转)

    如何捕获 System.loadLibrary 产生的异常? 当使用以下代码时,会发现异常处理的代码根本不会被执行: try{ System.loadLibrary("SimpleAuthe ...

  4. ACE .i .inl文件(转)

    在ACE的源代码目录里,有源文件.cpp.头文件.h,我们还发现有以.i和.inl为扩展名的文件.其实,以.i和.inl为扩展名的文件是ACE源码中inline函数的存放形式. 在说明ACE中为什么采 ...

  5. 配置Jenkins的slave节点的详细步骤适合windows等其他平台

    @  新建一个slave节点在Jenkins服务器上 1,进入Jenkins的主界面,进入"Manage Jenkins" 页面: 2,点击如下图中的"Manage  N ...

  6. Ubuntu中的Gif动画录制工具

    为了在随笔中插入gif动态图Windows系统上可以使用ScreenToGif这个非常好用的小软件,在Ubuntu系统中选择也很多(可以参考最下面的链接),下面介绍两款ubuntu系统中的录屏软件: ...

  7. Dom4j操作XML实战,解析和插入XML实例

    本例子是用XML来代替数据库的,XML的每个节点代替数据库一行数据. 直说过程: XML文件结构:定义了一个名为:User.xml的文件: <?xml version="1.0&quo ...

  8. 转 configure: error: Cannot find ldap libraries in /usr/lib 解决办法

    今天在centos 6.2 64位版本上安装LNMP,config php的时候出现下面错误而退出 configure: error: Cannot find ldap libraries in /u ...

  9. svn 命令行下常用的几个命令

    1.将文件checkout到本地目录    svn checkout path(path是服务器上的目录)    例如:svn checkout svn://192.168.1.1/pro/domai ...

  10. Jmeter+maven+Jenkins构建云性能测试平台(mark 推荐)

    转自:http://www.cnblogs.com/victorcai0922/archive/2012/06/20/2555502.html Jmeter+maven+Jenkins构建云性能测试平 ...