ThinkPHP5 数据库事务 - 03

xiaoxiao2021-02-28  117

MySQL :

CREATE DATABASE IF NOT EXISTS `db1` DEFAULT CHARACTER SET utf8 ;

USE `db1`; CREATE TABLE `think_data` (   `user_id` int(8) unsigned NOT NULL AUTO_INCREMENT,   `user_name` varchar(255) NOT NULL COMMENT '名称',   `deposit` decimal(18,4) DEFAULT NULL,   PRIMARY KEY (`user_id`) ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8; insert  into `think_data`(`user_id`,`user_name`,`deposit`) values (1,'Tim','5000.0000'),(2,'Jason','8000.0000'),(3,'Tom','12001.0000'),(4,'Jack','800051.0000'),(5,'Frank','35009.0000'),(6,'Tina','100.0000'),(7,'Suman','3759.0000'),(8,'Linda','5490.0000');

DELIMITER // -- 不要省略双斜线 否则无法创建存储过程 CREATE PROCEDURE transfer(IN from_id INT,IN to_id INT,money DECIMAL(18,4)) BEGIN     DECLARE CheckError INTEGER;     DECLARE    CONTINUE HANDLER FOR SQLEXCEPTION SET CheckError = 1;     START TRANSACTION;         UPDATE think_data SET deposit = deposit - money WHERE think_data.user_id = from_id ;     UPDATE think_data SET deposit = deposit + money WHERE think_data.user_id = to_id ;         INSERT INTO think_data VALUES    (3, 'Rainly',3600.50); -- 人为的制造一个主键重复的错误         IF CheckError = 1 THEN             ROLLBACK;         ELSE             COMMIT;         END IF;      SELECT * FROM think_data WHERE think_data.`user_id` IN(from_id,to_id); -- 返回修改后的记录集合不能放在回滚操作的前面 END; // -- 不要省略双斜线 否则无法创建存储过程

-- 执行存储过程的方式:

CALL transfer(5,6,3000)

[root@contoso ~]# cat /dev/null > /var/log/mariadb/queries.log && tail -f /var/log/mariadb/queries.log 170805 14:43:44    10 Query     CALL transfer(5,6,3000) 编号为5的账户转账给账户为6的用户 3000元失败了 发生了回滚,测试成功!

INSERT INTO think_data VALUES    (3, 'Rainly',3600.50); -- 人为的制造一个主键重复的错误,只要将这条抛出异常的插入操作去掉就是个非常标准存储过程事务

ThinkPHP5 原生SQL事务实现

apps/index/controller/User.php :

<?php namespace app\index\controller; use think\Controller; use think\Request; use think\Db; use PDO; class User extends Controller {     /**      * 显示资源列表      *      * @return \think\Response      */     public function index()     {         $from_id = 5;         $to_id = 6;         $money = 3000.54;         // 启动事务         $db1 = Db::connect('db1');         $db1->startTrans();         try{             $db1->execute(                 'UPDATE think_data SET deposit = deposit - ? WHERE think_data.user_id = ?',                 [[$money,PDO::PARAM_INT],[$from_id,PDO::PARAM_INT]]             );             $db1->execute(                 'UPDATE think_data SET deposit = deposit + ? WHERE think_data.user_id = ?',                 [[$money,PDO::PARAM_INT],[$to_id,PDO::PARAM_INT]]             );             // $db1->execute('INSERT INTO think_data VALUES    (3, \'Rainly\',3600.50)');             $db1->commit();         } catch (\Exception $e){             $db1->rollback();         }         $resultSet = $db1->query(             'SELECT * FROM think_data WHERE think_data.`user_id` IN(?,?)',             [[$from_id,PDO::PARAM_INT],[$to_id,PDO::PARAM_INT]]         );         var_dump($resultSet);     }     /**      * 显示创建资源表单页.      *      * @return \think\Response      */     public function create()     {     }     /**      * 保存新建的资源      *      * @param  \think\Request $request      * @return \think\Response      */     public function save(Request $request)     {     }     /**      * 显示指定的资源      *      * @param  int $user_id      * @return \think\Response      */     public function read($user_id)     {     }     /**      * 显示编辑资源表单页.      *      * @param  int $user_id      * @return \think\Response      */     public function edit($user_id)     {     }     /**      * 保存更新的资源      *      * @param  \think\Request $request      * @param  int $user_id      * @return \think\Response      */     public function update(Request $request, $user_id)     {     }     /**      * 删除指定资源      *      * @param  int $user_id      * @return \think\Response      */     public function delete($user_id)     {     }     public function miss()     {     } }

路由配置 apps/route.php :

<?php use think\Route; //主表路由(分组路由配置顺序必须是从表路由优先配置,否则从表路由一直会路由到主表控制器的方法上) Route::group(['name'=>'users','prefix'=>'index/User/'], function() {     Route::get('create$','create',['merge_extra_vars'=>true]);     Route::post('/$','save',['merge_extra_vars'=>true]);     Route::get(':user_id/edit$','edit',['merge_extra_vars'=>true]);     Route::get(':user_id$','read',['merge_extra_vars'=>true]);     Route::put(':user_id$','update',['merge_extra_vars'=>true]);     Route::delete(':user_id$','delete',['merge_extra_vars'=>true]);     Route::get('/$','index',['merge_extra_vars'=>true]);     Route::miss('miss'); // 在根资源路由里面写miss路由 }, [], ['user_id' => '\d+']); // create GET  http://contoso.org/users/create // save   POST http://contoso.org/users // edit   GET  http://contoso.org/users/10/edit // read   GET  http://contoso.org/users/10 // update PUT  http://contoso.org/users/10 // delete DELETE http://contoso.org/users/10 // index  GET  http://contoso.org/users

转载请注明原文地址: https://www.6miu.com/read-25746.html

最新回复(0)