You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
pdd-order-api/app/libs/tool/class.DbTool.php

206 lines
6.3 KiB
PHP

<?php
use Dao\AbstractDao;
use Exception\BaseRuntimeException;
use Exception\DbTransationException;
class DbTool {
const LOG_SQL_MODE_NONE = 0;
const LOG_SQL_MODE_FILE = 1;
const LOG_SQL_MODE_API = 2;
public static $logSqlMode = self::LOG_SQL_MODE_NONE;
private static $debugSqls = [];
private static $transactionMap = [];
private static $currentErrorMode = null;
private static $oldErrorMode = null;
const EMPTY_QUERY = '__EMPTY__';
/**
* @throws DbTransationException
*/
public static function transaction($transationFunc, $groupNameOrDbId = '', $execptionFunc = null, $isThrowException = true) {
$db = Zc::getDb();
$dbErrorLog = Zc::getLog('db_error');
try {
$oldErrorMode = $db->setErrorMode(ZcDb::ERROR_MODE_EXCEPTION);
$transStatus = $db->startTransaction(false, $groupNameOrDbId);
$transationFunc($db);
$db->commit($transStatus);
return true;
} catch (Exception $ex) {
$db->rollback($transStatus);
is_callable($execptionFunc) && $execptionFunc($ex);
if ($ex instanceof BaseRuntimeException) {
if ($isThrowException) {
throw $ex;
}
} else {
$dbErrorLog->error($ex->getMessage());
if ($isThrowException) {
throw new DbTransationException('数据错误', '', $ex->getMessage());
}
}
return false;
} finally {
$db->setErrorMode($oldErrorMode);
}
}
public static function exceptionMode() {
if (self::$currentErrorMode == ZcDb::ERROR_MODE_EXCEPTION) {
return;
}
$oldErrorMode = Zc::getDb()->setErrorMode(ZcDb::ERROR_MODE_EXCEPTION);
self::$currentErrorMode = ZcDb::ERROR_MODE_EXCEPTION;
if (is_null(self::$oldErrorMode)) {
self::$oldErrorMode = $oldErrorMode;
} elseif (self::$oldErrorMode == ZcDb::ERROR_MODE_EXCEPTION) {
self::$oldErrorMode = null;
}
}
public static function boolMode() {
if (is_null(self::$currentErrorMode) || self::$currentErrorMode == ZcDb::ERROR_MODE_BOOL) {
return;
}
$oldErrorMode = Zc::getDb()->setErrorMode(ZcDb::ERROR_MODE_BOOL);
self::$currentErrorMode = ZcDb::ERROR_MODE_BOOL;
if (is_null(self::$oldErrorMode)) {
self::$oldErrorMode = $oldErrorMode;
} elseif (self::$oldErrorMode == ZcDb::ERROR_MODE_BOOL) {
self::$oldErrorMode = null;
}
}
public static function resetErrorMode() {
if (!self::$oldErrorMode) {
return;
}
Zc::getDb()->setErrorMode(self::$oldErrorMode);
self::$currentErrorMode = self::$oldErrorMode;
self::$oldErrorMode = null;
}
public static function beginTrans($daoClass = '') {
if ($daoClass) {
/**
* @var AbstractDao $dao
*/
$dao = $daoClass::instance();
$dbId = $dao->getDbId();
} else {
$dbId = 'zc';
}
if (self::$transactionMap[$dbId]) {
throw new DbTransationException('事务重复', ErrorCodeConst::systemDbTransactionRepeat);
}
$db = Zc::getDb();
self::exceptionMode();
self::$transactionMap[$dbId] = $db->startTransaction(false, $dbId);
return self::$transactionMap[$dbId];
}
/**
* @param ZcTransactionStatus $trans
*/
public static function commitTrans($trans) {
if (!($trans instanceof ZcTransactionStatus)) {
throw new DbTransationException('事务错误', ErrorCodeConst::systemDbTransactionEmpty);
}
$conn = $trans->getConnection();
$dbId = $conn->getDbId();
$dbId = explode('.', $dbId)[0];
Zc::getDb()->commit($trans);
unset(self::$transactionMap[$dbId]);
if (empty(self::$transactionMap)) {
self::resetErrorMode();
}
}
/**
* @param ZcTransactionStatus $trans
*/
public static function rollbackTrans($trans) {
if (!($trans instanceof ZcTransactionStatus)) {
throw new DbTransationException('事务错误', ErrorCodeConst::systemDbTransactionEmpty);
}
$conn = $trans->getConnection();
$dbId = $conn->getDbId();
$dbId = explode('.', $dbId)[0];
$dbId = explode('.', $dbId)[0];
Zc::getDb()->rollback($trans);
unset(self::$transactionMap[$dbId]);
if (empty(self::$transactionMap)) {
self::resetErrorMode();
}
}
public static function rollbackAllTrans($isFromJmonitorDbListener = false) {
if ($isFromJmonitorDbListener) {
self::boolMode();
}
foreach (self::$transactionMap as $dbId => $trans) {
self::rollbackTrans($trans);
}
}
public static function hasLogSqlMode($mode) {
return (self::$logSqlMode & $mode) == $mode;
}
public static function isLogSql() {
return self::$logSqlMode != self::LOG_SQL_MODE_NONE;
}
public static function startLogSql($mode = self::LOG_SQL_MODE_FILE) {
self::$logSqlMode = $mode;
}
public static function endLogSql() {
self::$logSqlMode = self::LOG_SQL_MODE_NONE;
}
public static function logSql($sqlMsg) {
if (!CommonTool::isAllowDebug()) {
return;
}
if (self::hasLogSqlMode(self::LOG_SQL_MODE_API)) {
self::addDebugSql($sqlMsg);
}
if (self::hasLogSqlMode(DbTool::LOG_SQL_MODE_FILE) && Zc::C('env') != 'live') {
$sqlLog = Zc::getLog('db/sql');
$sqlLog->info($sqlMsg);
}
}
public static function addDebugSql($sqlMsg) {
self::$debugSqls[] = $sqlMsg;
}
public static function getDebugSqls() {
return self::$debugSqls;
}
public static function addLogSqlMode($mode) {
self::$logSqlMode = (self::$logSqlMode | $mode);
}
public static function removeLogSqlMode($mode) {
self::$logSqlMode = (self::$logSqlMode ^ $mode);
}
}