PHP code example of watsonhaw / think-orm

1. Go to this page and download the library: Download watsonhaw/think-orm library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

watsonhaw / think-orm example snippets


class Order extends Model
{
    // Before:直接赋值,随本次 insert 一起写入
    public static function onBeforeInsert($model)
    {
        $model->order_no = date('YmdHis') . mt_rand(1000, 9999);
        $model->status   = 0;
    }

    // After:如需持久化需显式 save()
    public static function onAfterInsert($model)
    {
        $model->extra = 'some value';
        $model->save(); // 触发 UPDATE
    }
}


namespace app\model;

use think\Model;
use think\model\concern\OptimLock;

class User extends Model
{
    use OptimLock;

    // 可选:自定义锁字段名,默认是 lock_version
    // protected $optimLock = 'version';

    protected $table = 'user';
    protected $pk = 'id';
}

$user = User::create([
    'name'  => '张三',
    'email' => '[email protected]',
]);

echo $user->lock_version; // 输出: 0

// 读取记录
$user = User::find(1);
echo $user->lock_version; // 输出: 0

// 修改并保存
$user->name = '李四';
$user->save();

echo $user->lock_version; // 输出: 1

// 再次读取验证
$fresh = User::find(1);
echo $fresh->lock_version; // 输出: 1

use think\db\exception\OptimLockException;

// 进程1读取记录
$user1 = User::find(1);

// 进程2读取同一条记录
$user2 = User::find(1);

// 进程1先更新
$user1->name = '进程1修改';
$user1->save(); // 成功,版本号变为 1

// 进程2尝试更新
try {
    $user2->name = '进程2修改';
    $user2->save();
} catch (OptimLockException $e) {
    // 捕获异常:记录已被其他进程修改
    echo "更新失败: " . $e->getMessage();
    echo "锁字段: " . $e->getLockField();           // lock_version
    echo "期望版本: " . $e->getExpectedVersion();    // 0
    echo "影响行数: " . $e->getAffectedRows();       // 0
}

function updateWithRetry($id, $newData, $maxRetries = 3)
{
    $retries = 0;
    while ($retries < $maxRetries) {
        try {
            $user = User::find($id);
            foreach ($newData as $key => $value) {
                $user->$key = $value;
            }
            $user->save();
            return $user;
        } catch (OptimLockException $e) {
            $retries++;
            if ($retries >= $maxRetries) {
                throw $e;
            }
            // 可选:加入短暂延迟避免频繁重试
            usleep(100000); // 100ms
        }
    }
}

// 使用
$result = updateWithRetry(1, ['name' => '最终修改名']);

use think\db\exception\OptimLockException;

$user1 = User::find(1);
$user2 = User::find(1);

// 先更新其中一个实例,改变版本号
$user1->name = '修改后';
$user1->save(); // 版本号 +1

try {
    // 尝试用旧版本号删除,会失败
    $user2->delete();
} catch (OptimLockException $e) {
    echo "删除失败: " . $e->getMessage();
}

// 强制更新,跳过版本号检查
$user->forceUpdateLock()->save();

// 强制删除,跳过版本号检查(也可以使用 force() 方法,与软删除共用)
$user->forceUpdateLock()->delete();
// 或者
$user->force()->delete();

class Goods extends Model
{
    use OptimLock;

    // 自定义乐观锁字段名为 version
    protected $optimLock = 'version';
}