Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Laravel中transaction小记 #34

Open
damoclesX opened this issue Feb 8, 2017 · 1 comment
Open

Laravel中transaction小记 #34

damoclesX opened this issue Feb 8, 2017 · 1 comment
Labels

Comments

@damoclesX
Copy link
Owner

公司某项目后端使用Laravel 5.0,作为只对后端略懂的前端,近日遇到一问题。

需求:

对两张表进行操作,一张表做更新操作,一张表做新增操作

分析:

使用数据库事务,Laravel提供现成的功能,代码大致如下

DB::beginTransaction();
  
try{
  //更新数据操作
  //新增数据操作

  DB::commit()
}catech(Exception $e){
  DB::rollBack()
}

ok,打完收工。无论是官方文档还是参看后端同事的代码都这样写的,突发奇想,想验证下,这个rollBack到底有没有效,于是在两条sql之间抛出一个异常,来模拟错误。代码如下:

DB::beginTransaction();
  
try{
  //更新数据操作
  throw new Exception('模拟错误');
  //新增数据操作

  DB::commit()
}catech(Exception $e){
  DB::rollBack()
}

果然,问题出现了。查看数据库,更新数据的操作已经反应到了数据库。这并不是想要的结果,说好的回滚呢?打断点调试,DB::rollBack也的确调用了。后面各种google,对比之前后端同事的代码,终于找到了原因。

事务是基于连接的,由于我遇到的情况比较特殊,要操作的这两张表在不同的数据库中,在两个不同的连接里面,而且两个都不是默认连接,直接调用DB::beginTransaction这些方法,操作的是默认连接。所以无法回滚。找到原因后,带上连接,代码如下:

$更新操作连接 = DB::connection('更新');
$新增操作连接 = DB::connection('新增');
$更新操作连接->beginTransaction();
$新增操作连接->beginTransaction();
  
try{
  //更新数据操作
  throw new Exception('模拟错误');
  //新增数据操作

  $更新操作连接->commit()
  $新增操作连接->commit()
}catech(Exception $e){
  $更新操作连接->rollBack()
  $新增操作连接->rollBack()
}

经测试,回滚成功,两个操作都成功的情况下,才成功。写法看起来很奇怪,感觉一下子多了很多代码,但确实有效,跨库操作的情况比较特殊。

彩蛋

解决问题过程中,发现Laravel5.0官方文档和各种教程 rollBack 写得都是 rollback 。虽然php在方法名不区分大小写,还是建议都写成rollBack(Laravel5.4版本的官方文档都是rollBack了),不然像我这种只对后端略懂的前端,看到写个rollback也能调用rollBack,简直是大吃一惊,还以为Laravel做了什么神奇的操作。

@no-serve-people
Copy link

刚刚也遇到这个问题。。。哈哈哈,不过是谷歌解决的

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants