mysql-Innodb事务隔离级别-repeatable read详解(转)

https://www.cnblogs.com/zhoujinyi/p/3437475.html

其中对“幻读”进行了详情说明,以前对这个词的理解有些偏差。

④ 幻读:第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。

mysql>CREATE TABLE `t_bitfly` (
`id` bigint(20) NOT NULL default '0',
`value` varchar(32) default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB

mysql> select @@global.tx_isolation, @@tx_isolation;
+-----------------------+-----------------+
| @@global.tx_isolation | @@tx_isolation  |
+-----------------------+-----------------+
| REPEATABLE-READ       | REPEATABLE-READ |
+-----------------------+-----------------+

实验一:

t Session A                   Session B
|
| START TRANSACTION;          START TRANSACTION;
|
| SELECT * FROM t_bitfly;
| empty set
|                             INSERT INTO t_bitfly
|                             VALUES (1, 'a');
|
| SELECT * FROM t_bitfly;
| empty set
|                             COMMIT;
|
| SELECT * FROM t_bitfly;
| empty set
|
| INSERT INTO t_bitfly VALUES (1, 'a');
| ERROR 1062 (23000):
| Duplicate entry '1' for key 1
v (shit, 刚刚明明告诉我没有这条记录的)

如此就出现了幻读,以为表里没有数据,其实数据已经存在了,傻乎乎的提交后,才发现数据冲突了。

实验二:

t Session A                  Session B
|
| START TRANSACTION;         START TRANSACTION;
|
| SELECT * FROM t_bitfly;
| +------+-------+
| | id   | value |
| +------+-------+
| |    1 | a     |
| +------+-------+
|                            INSERT INTO t_bitfly
|                            VALUES (2, 'b');
|
| SELECT * FROM t_bitfly;
| +------+-------+
| | id   | value |
| +------+-------+
| |    1 | a     |
| +------+-------+
|                            COMMIT;
|
| SELECT * FROM t_bitfly;
| +------+-------+
| | id   | value |
| +------+-------+
| |    1 | a     |
| +------+-------+
|
| UPDATE t_bitfly SET value='z';
| Rows matched: 2  Changed: 2  Warnings: 0
| (怎么多出来一行)
|
| SELECT * FROM t_bitfly;
| +------+-------+
| | id   | value |
| +------+-------+
| |    1 | z     |
| |    2 | z     |
| +------+-------+

本事务中第一次读取出一行,做了一次更新后,另一个事务里提交的数据就出现了。也可以看做是一种幻读。
当隔离级别是可重复读,且禁用innodb_locks_unsafe_for_binlog的情况下,在搜索和扫描index的时候使用的next-key locks可以避免幻读。

亿级用户下的新浪微博平台架构

序言

新浪微博在2014年3月公布的月活跃用户(MAU)已经达到1.43亿,2014年新年第一分钟发送的微博达808298条,如此巨大的用户规模和业务量,需要高可用(HA)、高并发访问、低延时的强大后台系统支撑。

微博平台第一代架构为LAMP架构,数据库使用的是MyIsam,后台用的是php,缓存为Memcache。

随着应用规模的增长,衍生出的第二代架构对业务功能进行了模块化、服务化和组件化,后台系统从php替换为Java,逐渐形成SOA架构,在很长一段时间支撑了微博平台的业务发展。 Continue reading

SSO单点登录的实现

1、为什么要做SSO?

在猎豹移动游戏开放平台刚开始的时候,我们的首要需求是实现OAuth2协议来为CP提供接入功能。
但随着我们的项目在发展,论坛、客服、用户中心也进行开发以及展望,不同的系统之间,帐号需要互通,实现单点登录,因此SSO应运而生。
也许有人说OAuth2也能实现单点登录,为什么不直接所有的系统都通过OAuth协议来实现统一登录。
对于大型的平台,SSO单点登录是必须的。OAuth给用户资源的授权提供了一个安全的、开放而又简易的标准,能够更安全、更方便的给第三方提供某些用户授权的信息。但和OAuth不同的是,对于我们自己的系统来说,不需要进行授权就能让用户进行使用。
一个很好的例子就是腾讯的QQ登录功能,对于第三方例如京东,就是使用OAuth协议进行授权,而对于腾讯微博、QQ空间,则是通过SSO来实现单点登录。

 

2、如何实现SSO?

SSO有以下几种方式实现:

  • 共享Cookie,这种是我们最先采取的方式。当我们的子系统都在一个父级域名下时,我们可以将Cookie种在父域下,这样浏览器同域名下的Cookie则可以共享,这样可以通过Cookie加解密的算法获取用户SessionID,从而实现SSO。
    但是,后面我们发现这种方式有几种弊端:
    a. 所有同域名的系统都能获取SessionID,易被修改且不安全;
    b. 跨域无法使用。
    所以到后面抛弃这种做法。
  • Ticket验证,我们目前采取的是这种方式。这种实现的SSO有以下几个步骤:
    a. 用户访问某个子系统,发现如果未登录,则引导用户跳转到SSO登录页面;
    b. 判断SSO是否已经登录;
    c. 如果已经登录,直接跳转到回调地址,并返回认证ticket;
    d. 如果未登录,用户正确输入用户名/密码,认证通过跳转到回调地址,并返回认证ticket;
    e. 子系统获取ticket,调用SSO获取用户uid等信息,成功后让用户登录。

Continue reading

用PHP尝试RabbitMQ(amqp扩展)实现消息的发送和接收

上篇文章我们介绍了amqp扩展在windows下的安装方法,这里我们看一下用法。

消费者:接收消息

逻辑:
创建连接–>创建channel–>创建交换机–>创建队列–>绑定交换机/队列/路由键–>接收消息

<?php
/*************************************
* PHP amqp(RabbitMQ) Demo - consumer
* Author: Linvo
* Date: 2012/7/30
*************************************/
//配置信息
$conn_args = array(
    'host' => '192.168.1.93',
    'port' => '5672',
    'login' => 'guest',
    'password' => 'guest',
    'vhost'=>'/'
);
$e_name = 'e_linvo'; //交换机名
$q_name = 'q_linvo'; //队列名
$k_route = 'key_1'; //路由key

//创建连接和channel
$conn = new AMQPConnection($conn_args);
if (!$conn->connect()) {
    die("Cannot connect to the broker!\n");
}
$channel = new AMQPChannel($conn);

//创建交换机
$ex = new AMQPExchange($channel);
$ex->setName($e_name);
$ex->setType(AMQP_EX_TYPE_DIRECT); //direct类型
$ex->setFlags(AMQP_DURABLE); //持久化
echo "Exchange Status:".$ex->declare()."\n";

//创建队列
$q = new AMQPQueue($channel);
$q->setName($q_name);
$q->setFlags(AMQP_DURABLE); //持久化
echo "Message Total:".$q->declare()."\n";

//绑定交换机与队列,并指定路由键
echo 'Queue Bind: '.$q->bind($e_name, $k_route)."\n";

//阻塞模式接收消息
echo "Message:\n";
while(True){
    $q->consume('processMessage');
    //$q->consume('processMessage', AMQP_AUTOACK); //自动ACK应答
}
$conn->disconnect();

/**
* 消费回调函数
* 处理消息
*/
function processMessage($envelope, $queue) {
    $msg = $envelope->getBody();
    echo $msg."\n"; //处理消息
    $queue->ack($envelope->getDeliveryTag()); //手动发送ACK应答
}

生产者:发送消息

逻辑:
创建连接–>创建channel–>创建交换机对象–>发送消息 Continue reading

windows下安装rabbitmq的php扩展amqp(原创)

从php官方下载相应的版本http://pecl.php.net/package/amqp,我这里使用的是1.4.0版本(http://pecl.php.net/package/amqp/1.4.0/windows
根据当前使用的php版本选择相应的扩展dll,下载后是一个压缩包,里面有两个dll扩展(php_amqp.dll和rabbitmq.1.dll)。

php_amqp

我的环境是64位的,php5.5.12.所以使用的是http://windows.php.net/downloads/pecl/releases/amqp/1.4.0/php_amqp-1.4.0-5.5-ts-vc11-x64.zip

1.将php_amqp.dll放在php的ext目录里,然后修改php.ini文件,在文件的最后面添加两行

[shell][amqp]
extension=php_amqp.dll[/shell]

2.将rabbitmq.1.dll文件放在php的根目录里(也就是ext目录的父级目录),然后修改apache的httpd.con文件,文件尾部添加一行

[shell]LoadFile "d:/wamp/bin/php/php5.5.12/rabbitmq.1.dll"[/shell]

这里的路径根据情况修改,我这里使用的wampserver软件。

3.重启apache,并查看phpinfo信息。只要看到amqp 字样即可。

amqp

下面我们看一下rabbitmq扩展amqp的用法:用PHP尝试RabbitMQ(amqp扩展)实现消息的发送和接收

关于Pull Request的十个建议(转)

Pull Request是Bitbucket、GitHub等源代码托管系统为了方便开发者之间协作而提供的一个功能,它提供了一个用户友好的Web界面来帮助审查人员进行代码审查。开发人员可以通过GitHub发出Pull Requests要求请求他人将程序拉下来进行代码审查。一个好的Pull Request不仅仅只是代码的事情,还牵涉到代码审查者对代码的审查,所以开发者不仅要写出好的代码,还必须迎合审查者的审查工作,才能给使得自己贡献的代码顺利通过审查并合并到master分支。现对丹麦的程序员、软件架构师、独立顾问Mark Seemann在自己博客中发布的一篇题为《关于Pull Request的十个建议》的文章进行一个全面的整理,以供读者阅读和参考。具体内容如下:

1. 进行较小的Pull Request

一个小且集中的Pull Request会使得提交的代码更加容易通过审核。据Mark Seemann根据自己的经验透漏,对提交代码进行审查所花费的时间是随着代码大小呈指数增长,而非线性增长;Pull Request多大才合适与Pull Request做了什么相关,最好少于12个文件的改变。如果Pull Request非常大,审查者就需要安排连续、相对比较长的时间进行审查,就会造成审查过程的延迟。 Continue reading

centos7无ifconfig命令的解决办法

最小化安装了centos7。默认情况下是没有ifconfig这个命令的,可以使用ip命令代替ifconfig,使用“ip addr”和“ip link”命令来查找网卡详情。不过也可以手动安装此命令。

执行以下命令即可。

[shell]yum -y install net-tools[/shell]

[英文]https://www.unixmen.com/ifconfig-command-found-centos-7-minimal-installation-quick-tip-fix/

http://linux.cn/article-3631-1.html