notrom进阶以及事务操作

2018-11-21 21:29 更新

PHALAPI-进阶篇4(NOTROM进阶以及事务操作)

前言

先在这里感谢phalapi框架创始人@dogstar,为我们提供了这样一个优秀的开源框架.

写本篇教程的起因是在于在交流的时候有位童鞋提出了fetchPairs有BUG,原来一直没有仔细的了解过notorm的细节,趁这次机会主要把notorm之中的一些方便快捷的操作简单的说明一下,以及对与事务操作做一些我自己的简介以及使用notorm如何实现.

附上:

喵了个咪的博客:w-blog.cn

官网地址:http://www.phalapi.net/

开源中国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. 事务操作

其实很大一部分使用事务的目的是应为害怕并发的情况下导致,对数据库造成重复的操作,比如如下场景:

应用审核,有两个管理者对同一个应用审核,一个成功一个失败,然后是同时请求过来的,一起到了查询应用状态发现都是未审核,然后都去进行了审核操作,这个时候两个操作返回的都是审核成功,但是有一个人会看到审核状态和自己的审核结果不同,这个就是问题了,大部分解决此类问题时都会考虑到使用数据库事务操作,其实对于事务操作我的建议是能不用尽量不要使用,我简单聊一下我的几个观点

  1. 是否真的那么重要,对于上面的问题也许乍一看上去感觉,这样怎么可以呢,但是仔细想一想,这两个操作都是属于我们管理者的正常的操作,真正对于业务来说我认为是没有问题的,当然这是因为影响不大,如果是付款,一个订单从两个地方同时付款然后都发现是未付款,然后都进行了付款,这种业务就必须有处理方式了,所以是否使用事务要看业务是否非常需求

  2. 概率是怎么样的,对于一个程序来说,两条请求刚好通过了查询过程,一同到了修改的时候,不管是什么场景发生这种并发冲突的可能性是极其微小的,我觉得几乎可以忽略(当然前提是重要性没有那么的高,我们不能以偏概全)

  3. 曲线救国其实我们可以使用其他方式避免这种问题,我们可以把我们需要验证条件加入到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 欢迎大家的加入!

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号