#phalapi-进阶篇4(notrom进阶以及事务操作)#
##前言## 先在这里感谢phalapi框架创始人@dogstar,为我们提供了这样一个优秀的开源框架.
写本篇教程的起因是在于在交流的时候有位童鞋提出了fetchPairs有BUG,原来一直没有仔细的了解过notorm的细节,趁这次机会主要把notorm之中的一些方便快捷的操作简单的说明一下,以及对与事务操作做一些我自己的简介以及使用notorm如何实现.
附上:
开源中国Git地址:http://git.oschina.net/dogstar/PhalApi/tree/release
##1. 进一步了解notorm##
在notorm有很多方便并没有在PhalApi官方文档中有并没有非常详细的介绍过,在这里把一些可能会用到的notorm函数坐下介绍以及功能
###1.1 fetchPairs###
fetchPairs的使用和fetchAll相似但是他有一个特别之处,fetchPairs需要传递一个参数,这个参数是字符串的key值(比如 name id)当传递之后会出现这样的对比效果
DI()->notorm->user->fetchPairs('name');
DI()->notorm->user->fetchAll('name');
大家有看到区别吗?
嗯!是在返回的时候把在之前定义的key值放到了返回数组的key中
提示:在老版本中在使用过程中 Result.php 会有一句 821行的报错需要把
$values = array_values(iterator_to_array($row));
改成
$values = array_values($row);
###1.2 lock ###
lock操作是一种锁的行为,对于整表进行锁定,在当前用户释放锁之前此表不能在被操作,lock接受一个bool参数,默认是true锁表,使用如下
$userdb = DI()->notorm->user->lock(); //锁定表
$rs = $userdb->fetchAll();
生成的sql语句如下:
SELECT * FROM user FOR UPDATE;
###1.3 加操作###
在很多时候我们会用到,数据库里面某个值+1或者是其他,我们不能在update的时候写入array('key' => 'key+1')因为在解析sql的时候 key+1 会带上引号作为一个字符串处理,当然是有解决方法的,如下
DI()->notorm->user->where('id', 1)->update(array('sum' => new NotORM_Literal("sum + 1")));
这样就可以生成不带引号的操作了
UPDATE user SET phone = sum + 1 WHERE (id = 1);
###1.4 group ###
group是去重操作,在notorm里面也封装的有,我们可以使用group用于统计有多少同名的用户等一些统计操作,或者是找出库里面不重复的城市名
DI()->notorm->user->select('name , count(*) as count')->group('name')->fetchAll();
会获得如下结果
###1.5 快速函数sum,count,max,min ###
在我们使用过程中虽然使用这类操作不是很多,但是使用notorm的快速函数依然感觉很方便,
return DI()->notorm->user->sum('id'); //做加法
return DI()->notorm->user->max('id'); //获取这个key中最大的值
return DI()->notorm->user->min('id'); //获取这个key中最小的值
return DI()->notorm->user->count(); //统计一共几条数据
##2. 事务操作##
其实很大一部分使用事务的目的是应为害怕并发的情况下导致,对数据库造成重复的操作,比如如下场景:
应用审核,有两个管理者对同一个应用审核,一个成功一个失败,然后是同时请求过来的,一起到了查询应用状态发现都是未审核,然后都去进行了审核操作,这个时候两个操作返回的都是审核成功,但是有一个人会看到审核状态和自己的审核结果不同,这个就是问题了,大部分解决此类问题时都会考虑到使用数据库事务操作,其实对于事务操作我的建议是能不用尽量不要使用,我简单聊一下我的几个观点
-
是否真的那么重要,对于上面的问题也许乍一看上去感觉,这样怎么可以呢,但是仔细想一想,这两个操作都是属于我们管理者的正常的操作,真正对于业务来说我认为是没有问题的,当然这是因为影响不大,如果是付款,一个订单从两个地方同时付款然后都发现是未付款,然后都进行了付款,这种业务就必须有处理方式了,所以是否使用事务要看业务是否非常需求
-
概率是怎么样的,对于一个程序来说,两条请求刚好通过了查询过程,一同到了修改的时候,不管是什么场景发生这种并发冲突的可能性是极其微小的,我觉得几乎可以忽略(当然前提是重要性没有那么的高,我们不能以偏概全)
-
曲线救国其实我们可以使用其他方式避免这种问题,我们可以把我们需要验证条件加入到Update的条件中这样两条语句总归会有一条语句执行失败
那么我们使用notorm中解决此类需要用到事务的问题呢
notorm提供了常规的事务操作如下
//第一步:先指定待进行事务的数据库(通过获取一个notorm表实例来指定;否则会提示:PDO There is no active transaction)
$user = DI()->notorm->user;
//第二步:开启事务开关(此开关会将当前全部打开的数据库都进行此设置)
DI()->notorm->transaction = 'BEGIN';
//第三步:进行数据库操作
$user->insert(array('name' => 'test3',));
$user->insert(array('name' => 'test4',));
//第四:提交/回滚
DI()->notorm->transaction = 'COMMIT';
//DI()->notorm->transaction = 'ROLLBACK';
还有一种处理方式就是在操作之前进行lock锁表
$user = DI()->notorm->user;
$user->lock();
$user->insert(array('name' => 'test3',));
$user->insert(array('name' => 'test4',));
这两种方式大家可以自行取舍
注:在phalapiV1.31版本后有自带提供事务操作可参考文档
##3. 总结##
在本小节中,对于notorm之中的一些特别的封装函数进行了一系列的介绍,以及对于事务提出了我的看法以及观点,和使用notorm的解决方案,希望看了这篇教程的童鞋对你的日常开发有所帮助
注:笔者能力有限有说的不对的地方希望大家能够指出,也希望多多交流!
官网QQ交流群:421032344 欢迎大家的加入!