什么是嵌套事务? 一般情况下我们都是一个
begin
, 一个commit
或rollBack
, 但是有可能我们有种场景需要begin
然后在事务里面再开一个事务, 这就是嵌套事务.MySQL
嵌套事务支持MySQL
里面有个savepoint
关键字, 可以模拟嵌套事务, 但事实上并不是真正的嵌套事务, 仍然是一个事务.savepoint
的用处, 我们可以回滚事务内的部分修改
Laravel
嵌套事务使用DB::beginTransaction()
里面再次使用DB::beginTransaction()
即可, 但需要注意开启事务的次数需要和commit
或rollBack
的次数对应
Lumen 单元测试的一些问题
一个 test 多个请求
如 $this->post
,然后又 $this->post
,我们会发现第二个请求中的请求参数是和第一个请求的参数是完全一样的, 然后在 Controller
里面通过 spl_object_hash
方法发现两个请求的 request
实例是一样的, 应该是第二个请求发起的时候,request
不再实例化,直接使用了上一次请求的 request
实例。
这种情况我们可以用过 request
实例的 replace
方法,替代掉 request
实例的请求参数,这样我们第二个请求就可以按照我们预期地跑了。
1 | $this->post('xxx', ['a' => 1]); |
使用 mock
的时候,mock
一个不存在的方法不会报错
其实这也算是 mock
本身要实现的功能,但是如果我们可能在调用多个对象的方法的时候会混淆,mock
了一个错误的对象的方法,但实际上应该是 mock
另外一个。
如果我们 mock
了之后,对象方法表现还是原来的样子就应该考虑一下是不是 mock
了一个错误的对象。
不能对 private
final
static
方法进行 mock
,需要对 mock
的对象调用 setMethods
,说明我们要对哪些方法进行 mock
,否则可能会报错。
Lumen 使用 Dingo API 在 PHPUnit 中 404 的解决方法, 以及鉴权问题
phpunit.xml
中添加 dingo
相关配置
1 | <env name="API_STANDARDS_TREE" value="x"/> |
dingo
的路由配置文件包含不能使用 require_once
。
否则, 可能会出现一种情况是, phpunit
中第一个请求成功了, 但是后面的请求都 404。
这里涉及到的一个知识点是:laravel 或 lumen phpunit
中每一个 test
都会使用独立的 Application
以及 TestCase
实例来运行,我们知道,框架在初始化的时候会加载路由的配置,如果我们的进程只跑一遍,这样其实没什么问题。
但是,phpunit
中的 TestCase
是,一个进程,然后一个 TestCase
里面有多少 test
方法,就会进行多少次框架的初始化操作,这样问题就出现了,后续的请求中,require_once
不能再读取到任何配置信息,因此导致了后续请求全部 404 了。
所以需要使用 require
代替 require_once
。
知识点:同一个进程中,require_once
只有第一次 require
会执行文件里面的内容,后续 require
不再加载文件。
在测试中添加以下方法调用
phpunit.xml
中添加dingo
相关配置
1 | <env name="API_STANDARDS_TREE" value="x"/> |
dingo
的路由配置文件包含不能使用require_once
。否则, 可能会出现一种情况是,phpunit
中第一个请求成功了, 但是后面的请求都 404在测试中添加以下方法调用
1 | public function setUp() |
控制台实时查看 Laravel 的 sql 操作
listen-sql 一个在控制台看到实时 sql 操作的工具
在 Laravel 中打印 sql,以往的做法往往是,通过 DB::listen
监听,然后通过 Log::info
写入到 log 中。
这样写入的 log,我们想查看往往是去 storage 文件夹下找到当天的 log 文件,然后打开。有个不好的地方是,如果在编辑器打开,往往不会实时更新。请求完之后,可能需要切到其他 tab 再切换回来才会更新。同时,太多的 sql 日志会和其他 log 混杂在一起,会显得有些混乱。
除此之外,也可以 tail -f storage/logs/xx.log
来实时查看 log 的输出。这样有个不好的地方是,如果在 config/app.php
定义了 log => 'daily'
,每天都要输入一个新的文件名。
现在,我们可以只使用一个命令来实现监听应用里的 sql 操作。

安装
1.通过 composer 安装 (eleven26/listen-sql)。
1 | composer require "eleven26/listen-sql:~1.0.2" |
2.注册 Service Provider
Laravel
: 修改文件config/app.php
,Laravel 5.5+
不需要1
2
3
4'providers' => [
//...
Eleven26\ListenSql\ListenSqlServiceProvider::class,
],Lumen
: 修改文件bootstrap/app.php
1
$app->register(Eleven26\ListenSql\ListenSqlServiceProvider::class);
使用
1 | php artisan listen-sql:start |
到这一步,去页面刷新的时候,就可以在控制台看到 sql
语句了
可以使用下面的命令
可以使用下面的命令
1 | php artisan migrate --pretend --no-ansi |
当然,你需要有可以 migrate 的东西。
数据库迁移导出到文件(使用命令)
1 | <?php |
上面的一些处理是把一些无效的信息去掉,如时间戳,这样最后剩下的就是可以直接执行的 sql 语句了。