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); } }