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.
206 lines
6.3 KiB
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);
|
|
}
|
|
} |