Log4net详细教程

article/2025/9/29 17:12:08

Log4net详细教程

  • 一、Log4net概述
    • log4net主要几个方法:
  • 二、配置教程
    • 1、配置文件详解
    • 2、程序配置文件
    • 3、日志帮助类的编写

一、Log4net概述

log4net 是从 java 下有卓越表现的 log4j 移植过来的,是一个能够将日志信息输出到各种 不同目标的.net 类库,主要作用是将程序调试和运行时的各种日志信息进行记录,通俗来讲log4net是一个帮助程序员将日志语句输出到各种输出目标的工具。log4net 包的设计使得日志语句可以保留在发布的代码中,而不会产生高性能成本。官网地址

log4net主要几个方法:

控制级别,由低到高: ALL | DEBUG | INFO | WARN | ERROR | FATAL | OFF,<level>标签下配置写入级别,写入配置级别以上日志。

日志类型如下
DEBUG:调试日志,开发完成后几乎不用,我一般都直接不写这个配置;
INFO:基本日志信息,最常用的;
WARN:警告日志信息,不常用;
ERROR:错误日志,异常日志信息,常用;
FATAL:致命错误日志信息,不常用;

二、配置教程

这篇博客适合Log4net小白,这里,你要清楚几个问题:log4net配置文件是什么结构?如何在程序代码上正确地调用配置文件?你要怎么配?你要实现什么样的逻辑功能?

此篇文章要实现的功能逻辑: 配置一个全局日志帮助类,能够给整个项目进行调用,其中,类方法这些,我写在功能模块上,其他项目通过引用生成好的公共模块dll文件正常调用日志帮助类里的静态方法。其中,我将配置上三种日志记录模式,以满足以后日志记录的功能需求:文件日志、控制台日志、数据库日志(我用Sql日志,它支持各种数据库)。

其中,我在文件日志再细分:默认文件日志、默认文件异常日志、管理员权限文件日志、管理员权限异常文件日志;
控制台日志再细分:默认控制台日志、控制台异常日志、有颜色的控制台日志、有颜色的控制台异常日志

1、配置文件详解

先直接贴我整个项目配好能用的源码如下:

<?xml version="1.0" encoding="utf-8" ?>
<configuration><configSections><section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/></configSections><!--站点日志配置部分--><log4net><!-- OFF, FATAL, ERROR, WARN, INFO, DEBUG, ALL --><!-- Set root logger level to ERROR and its appenders --><!--<root>:实际上就是一个根logger,所有其它logger都默认继承它支持子元素:appender-ref:0个或多个,要引用的appender的名字;level:最多一个。 只有在这个级别或之上的事件才会被记录;param:0个或多个, 设置一些参数;--><root><!--控制级别,由低到高: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF--><!--比如定义级别为INFO,则INFO级别向下的级别,比如DEBUG日志将不会被记录--><!--如果没有定义LEVEL的值,则默认为DEBUG--><level value="INFO"/></root><!--<logger>:支持的属性:name:必须的,logger的名称additivity:可选,取值是true或false,默认值是true。设置为false时将阻止父logger中的appender支持的子元素:appender-ref:0个或多个,要引用的appender的名字level:最多一个。 只有在这个级别或之上的事件才会被记录。param:0个或多个, 设置一些参数。--><!--只记录文件日志--><!--默认日志--><logger name="Default_File" additivity="false"><level value="INFO"/><appender-ref ref="DefaultLogFileAppender_Info"/><appender-ref ref="DefaultLogFileAppender_Debug"/><appender-ref ref="DefaultLogFileAppender_Warn"/><appender-ref ref="DefaultLogFileAppender_Error"/><appender-ref ref="DefaultLogFileAppender_Fatal"/></logger><!--默认异常日志--><logger name="Default_Ex_File" additivity="false"><level value="ERROR"/><appender-ref ref="DefaultLogFileAppender_Ex_Error"/><appender-ref ref="DefaultLogFileAppender_Ex_Fatal"/></logger><!--管理员权限日志--><logger name="Admin_File" additivity="false"><level value="INFO"/><appender-ref ref="AdminLogFileAppender_Info"/><appender-ref ref="AdminLogFileAppender_Debug"/><appender-ref ref="AdminLogFileAppender_Warn"/><appender-ref ref="AdminLogFileAppender_Error"/><appender-ref ref="AdminLogFileAppender_Fatal"/></logger><!--管理员权限异常日志--><logger name="Admin_Ex_File" additivity="false"><level value="ERROR"/><appender-ref ref="AdminLogFileAppender_Ex_Error"/><appender-ref ref="AdminLogFileAppender_Ex_Fatal"/></logger><!-- 控制台程序日志 --><logger name="ConsoleDefault" additivity="false"><level value="INFO"/><appender-ref ref="ConsoleAppender"/></logger><logger name="ColoredConsoleDefault" additivity="false"><level value="INFO"/><appender-ref ref="ColoredConsoleAppender"/></logger><!-- 控制台异常程序日志 --><logger name="ColoredConsoleDefault_Ex" additivity="false"><level value="ERROR"/><appender-ref ref="ConsoleAppender_Ex"/></logger><logger name="ColoredConsoleDefault_Ex" additivity="false"><level value="ERROR"/><appender-ref ref="ColoredConsoleAppender_Ex"/></logger><!-- SQL日志 --><logger name="DefaultLog_Sql" additivity="false"><level value="INFO"/><appender-ref ref="AdoNetAppender"/></logger><!-- 将日志写到文件中 --><appender name="DefaultLogFileAppender_Info" type="log4net.Appender.RollingFileAppender"><!--多线程时采用最小锁定:记录日志写入文件时,不锁定文本文件,防止多线程时不能写Log,官方说线程非安全--><lockingModel type="log4net.Appender.FileAppender+MinimalLock"/><!-- 不自动生成空白文件 --><lockingModel type="Common.Helper.MinimalLockDeleteEmpty"/><!--目录路径,可以是相对路径或绝对路径--><param name="File" value="log\\Info\\"/><!--文件名,按日期生成文件夹--><param name="DatePattern" value="/yyyy-MM/&quot;Info_&quot;MM-dd-HH&quot;.log&quot;"/><!--追加到文件--><appendToFile value="true"/><!--创建日志文件的方式,可选值:Date[日期],文件大小[Size],混合[Composite]--><rollingStyle value="Composite"/><preserveLogFileNameExtension value="true"/><!--写到一个文件--><staticLogFileName value="false"/><!--单个文件大小。单位:KB|MB|GB--><maximumFileSize value="5MB"/><!--最多保留的文件数,设为"-1"则不限--><maxSizeRollBackups value="20"/><!--日志格式--><layout type="log4net.Layout.PatternLayout"><param name="ConversionPattern" value="%n【%d】:%m%n" /></layout><!--限制只写信息日志--><filter type="log4net.Filter.LevelRangeFilter"><param name="LevelMin" value="INFO" /><param name="LevelMax" value="INFO" /></filter></appender><appender name="DefaultLogFileAppender_Debug" type="log4net.Appender.RollingFileAppender"><!--多线程时采用最小锁定:记录日志写入文件时,不锁定文本文件,防止多线程时不能写Log,官方说线程非安全--><lockingModel type="log4net.Appender.FileAppender+MinimalLock"/><!--目录路径,可以是相对路径或绝对路径--><param name="File" value="log\\Debug\\"/><!--文件名,按日期生成文件夹--><param name="DatePattern" value="/yyyy-MM/&quot;Debug_&quot;MM-dd-HH&quot;.log&quot;"/><!--追加到文件--><appendToFile value="true"/><!--创建日志文件的方式,可选值:Date[日期],文件大小[Size],混合[Composite]--><rollingStyle value="Composite"/><preserveLogFileNameExtension value="true"/><!--写到一个文件--><staticLogFileName value="false"/><!--单个文件大小。单位:KB|MB|GB--><maximumFileSize value="5MB"/><!--最多保留的文件数,设为"-1"则不限--><maxSizeRollBackups value="20"/><!--日志格式--><layout type="log4net.Layout.PatternLayout"><param name="ConversionPattern" value="%n【%d】:%m%n" /></layout><!--限制只写信息日志--><filter type="log4net.Filter.LevelRangeFilter"><param name="LevelMin" value="DEBUG" /><param name="LevelMax" value="DEBUG" /></filter></appender><appender name="DefaultLogFileAppender_Warn" type="log4net.Appender.RollingFileAppender"><!--多线程时采用最小锁定:记录日志写入文件时,不锁定文本文件,防止多线程时不能写Log,官方说线程非安全--><lockingModel type="log4net.Appender.FileAppender+MinimalLock"/><!-- 不自动生成空白文件 --><lockingModel type="Common.Helper.MinimalLockDeleteEmpty"/><!--目录路径,可以是相对路径或绝对路径--><param name="File" value="log\\Warn\\"/><!--文件名,按日期生成文件夹--><param name="DatePattern" value="/yyyy-MM/&quot;Warn_&quot;MM-dd-HH&quot;.log&quot;"/><!--追加到文件--><appendToFile value="true"/><!--创建日志文件的方式,可选值:Date[日期],文件大小[Size],混合[Composite]--><rollingStyle value="Composite"/><preserveLogFileNameExtension value="true"/><!--写到一个文件--><staticLogFileName value="false"/><!--单个文件大小。单位:KB|MB|GB--><maximumFileSize value="5MB"/><!--最多保留的文件数,设为"-1"则不限--><maxSizeRollBackups value="20"/><!--日志格式--><layout type="log4net.Layout.PatternLayout"><param name="ConversionPattern" value="%n【%d】:%m%n" /></layout><!--限制只写信息日志--><filter type="log4net.Filter.LevelRangeFilter"><param name="LevelMin" value="WARN" /><param name="LevelMax" value="WARN" /></filter></appender><appender name="DefaultLogFileAppender_Error" type="log4net.Appender.RollingFileAppender"><!--多线程时采用最小锁定:记录日志写入文件时,不锁定文本文件,防止多线程时不能写Log,官方说线程非安全--><lockingModel type="log4net.Appender.FileAppender+MinimalLock"/><!-- 不自动生成空白文件 --><lockingModel type="Common.Helper.MinimalLockDeleteEmpty"/><!--目录路径,可以是相对路径或绝对路径--><param name="File" value="log\\Error\\"/><!--文件名,按日期生成文件夹--><param name="DatePattern" value="/yyyy-MM/&quot;Error_&quot;MM-dd-HH&quot;.log&quot;"/><!--追加到文件--><appendToFile value="true"/><!--创建日志文件的方式,可选值:Date[日期],文件大小[Size],混合[Composite]--><rollingStyle value="Composite"/><preserveLogFileNameExtension value="true"/><!--写到一个文件--><staticLogFileName value="false"/><!--单个文件大小。单位:KB|MB|GB--><maximumFileSize value="5MB"/><!--最多保留的文件数,设为"-1"则不限--><maxSizeRollBackups value="20"/><!--日志格式--><layout type="log4net.Layout.PatternLayout"><param name="ConversionPattern" value="%n【%d】:%m%n" /></layout><!--限制只写信息日志--><filter type="log4net.Filter.LevelRangeFilter"><param name="LevelMin" value="ERROR" /><param name="LevelMax" value="ERROR" /></filter></appender><appender name="DefaultLogFileAppender_Fatal" type="log4net.Appender.RollingFileAppender"><!--多线程时采用最小锁定:记录日志写入文件时,不锁定文本文件,防止多线程时不能写Log,官方说线程非安全--><lockingModel type="log4net.Appender.FileAppender+MinimalLock"/><!-- 不自动生成空白文件 --><lockingModel type="Common.Helper.MinimalLockDeleteEmpty"/><!--目录路径,可以是相对路径或绝对路径--><param name="File" value="log\\Fatal\\"/><!--文件名,按日期生成文件夹--><param name="DatePattern" value="/yyyy-MM/&quot;Fatal_&quot;MM-dd-HH&quot;.log&quot;"/><!--追加到文件--><appendToFile value="true"/><!--创建日志文件的方式,可选值:Date[日期],文件大小[Size],混合[Composite]--><rollingStyle value="Composite"/><preserveLogFileNameExtension value="true"/><!--写到一个文件--><staticLogFileName value="false"/><!--单个文件大小。单位:KB|MB|GB--><maximumFileSize value="5MB"/><!--最多保留的文件数,设为"-1"则不限--><maxSizeRollBackups value="20"/><!--日志格式--><layout type="log4net.Layout.PatternLayout"><param name="ConversionPattern" value="%n【%d】:%m%n" /></layout><!--限制只写信息日志--><filter type="log4net.Filter.LevelRangeFilter"><param name="LevelMin" value="FATAL" /><param name="LevelMax" value="FATAL" /></filter></appender><appender name="DefaultLogFileAppender_Ex_Error" type="log4net.Appender.RollingFileAppender"><!--多线程时采用最小锁定:记录日志写入文件时,不锁定文本文件,防止多线程时不能写Log,官方说线程非安全--><lockingModel type="log4net.Appender.FileAppender+MinimalLock"/><!-- 不自动生成空白文件 --><lockingModel type="Common.Helper.MinimalLockDeleteEmpty"/><!--目录路径,可以是相对路径或绝对路径--><param name="File" value="log\\Error\\"/><!--文件名,按日期生成文件夹--><param name="DatePattern" value="/yyyy-MM/&quot;Error_&quot;MM-dd-HH&quot;.log&quot;"/><!--追加到文件--><appendToFile value="true"/><!--创建日志文件的方式,可选值:Date[日期],文件大小[Size],混合[Composite]--><rollingStyle value="Composite"/><preserveLogFileNameExtension value="true"/><!--写到一个文件--><staticLogFileName value="false"/><!--单个文件大小。单位:KB|MB|GB--><maximumFileSize value="5MB"/><!--最多保留的文件数,设为"-1"则不限--><maxSizeRollBackups value="20"/><!--日志格式--><layout type="log4net.Layout.PatternLayout"><param name="ConversionPattern" value="%n【%d】:%m%n【异常信息】:%exception%n" /></layout><!--限制只写信息日志--><filter type="log4net.Filter.LevelRangeFilter"><param name="LevelMin" value="ERROR" /><param name="LevelMax" value="ERROR" /></filter></appender><appender name="DefaultLogFileAppender_Ex_Fatal" type="log4net.Appender.RollingFileAppender"><!--多线程时采用最小锁定:记录日志写入文件时,不锁定文本文件,防止多线程时不能写Log,官方说线程非安全--><lockingModel type="log4net.Appender.FileAppender+MinimalLock"/><!-- 不自动生成空白文件 --><lockingModel type="Common.Helper.MinimalLockDeleteEmpty"/><!--目录路径,可以是相对路径或绝对路径--><param name="File" value="log\\Fatal\\"/><!--文件名,按日期生成文件夹--><param name="DatePattern" value="/yyyy-MM/&quot;Fatal_&quot;MM-dd-HH&quot;.log&quot;"/><!--追加到文件--><appendToFile value="true"/><!--创建日志文件的方式,可选值:Date[日期],文件大小[Size],混合[Composite]--><rollingStyle value="Composite"/><preserveLogFileNameExtension value="true"/><!--写到一个文件--><staticLogFileName value="false"/><!--单个文件大小。单位:KB|MB|GB--><maximumFileSize value="5MB"/><!--最多保留的文件数,设为"-1"则不限--><maxSizeRollBackups value="20"/><!--日志格式--><layout type="log4net.Layout.PatternLayout"><param name="ConversionPattern" value="%n【%d】:%m%n【异常信息】:%exception%n" /></layout><!--限制只写信息日志--><filter type="log4net.Filter.LevelRangeFilter"><param name="LevelMin" value="FATAL" /><param name="LevelMax" value="FATAL" /></filter></appender><!-- Admin_File管理员权限的日志 --><appender name="AdminLogFileAppender_Info" type="log4net.Appender.RollingFileAppender"><!--多线程时采用最小锁定:记录日志写入文件时,不锁定文本文件,防止多线程时不能写Log,官方说线程非安全--><lockingModel type="log4net.Appender.FileAppender+MinimalLock"/><!-- 不自动生成空白文件 --><lockingModel type="Common.Helper.MinimalLockDeleteEmpty"/><!--目录路径,可以是相对路径或绝对路径--><param name="File" value="log\\Info\\"/><!--文件名,按日期生成文件夹--><param name="DatePattern" value="/yyyy-MM/&quot;Info_&quot;MM-dd-HH&quot;.log&quot;"/><!--追加到文件--><appendToFile value="true"/><!--创建日志文件的方式,可选值:Date[日期],文件大小[Size],混合[Composite]--><rollingStyle value="Composite"/><preserveLogFileNameExtension value="true"/><!--写到一个文件--><staticLogFileName value="false"/><!--单个文件大小。单位:KB|MB|GB--><maximumFileSize value="5MB"/><!--最多保留的文件数,设为"-1"则不限--><maxSizeRollBackups value="20"/><!--日志格式--><layout type="log4net.Layout.PatternLayout"><param name="ConversionPattern" value="%n【%d】:%m%n【源码信息】:%location%n" /></layout><!--限制只写信息日志--><filter type="log4net.Filter.LevelRangeFilter"><param name="LevelMin" value="INFO" /><param name="LevelMax" value="INFO" /></filter></appender><appender name="AdminLogFileAppender_Debug" type="log4net.Appender.RollingFileAppender"><!--多线程时采用最小锁定:记录日志写入文件时,不锁定文本文件,防止多线程时不能写Log,官方说线程非安全--><lockingModel type="log4net.Appender.FileAppender+MinimalLock"/><!-- 不自动生成空白文件 --><lockingModel type="Common.Helper.MinimalLockDeleteEmpty"/><!--目录路径,可以是相对路径或绝对路径--><param name="File" value="log\\Debug\\"/><!--文件名,按日期生成文件夹--><param name="DatePattern" value="/yyyy-MM/&quot;Debug_&quot;MM-dd-HH&quot;.log&quot;"/><!--追加到文件--><appendToFile value="true"/><!--创建日志文件的方式,可选值:Date[日期],文件大小[Size],混合[Composite]--><rollingStyle value="Composite"/><preserveLogFileNameExtension value="true"/><!--写到一个文件--><staticLogFileName value="false"/><!--单个文件大小。单位:KB|MB|GB--><maximumFileSize value="5MB"/><!--最多保留的文件数,设为"-1"则不限--><maxSizeRollBackups value="20"/><!--日志格式--><layout type="log4net.Layout.PatternLayout"><param name="ConversionPattern" value="%n【%d】:%m%n【源码信息】:%location%n" /></layout><!--限制只写信息日志--><filter type="log4net.Filter.LevelRangeFilter"><param name="LevelMin" value="DEBUG" /><param name="LevelMax" value="DEBUG" /></filter></appender><appender name="AdminLogFileAppender_Warn" type="log4net.Appender.RollingFileAppender"><!--多线程时采用最小锁定:记录日志写入文件时,不锁定文本文件,防止多线程时不能写Log,官方说线程非安全--><lockingModel type="log4net.Appender.FileAppender+MinimalLock"/><!-- 不自动生成空白文件 --><lockingModel type="Common.Helper.MinimalLockDeleteEmpty"/><!--目录路径,可以是相对路径或绝对路径--><param name="File" value="log\\Warn\\"/><!--文件名,按日期生成文件夹--><param name="DatePattern" value="/yyyy-MM/&quot;Warn_&quot;MM-dd-HH&quot;.log&quot;"/><!--追加到文件--><appendToFile value="true"/><!--创建日志文件的方式,可选值:Date[日期],文件大小[Size],混合[Composite]--><rollingStyle value="Composite"/><preserveLogFileNameExtension value="true"/><!--写到一个文件--><staticLogFileName value="false"/><!--单个文件大小。单位:KB|MB|GB--><maximumFileSize value="5MB"/><!--最多保留的文件数,设为"-1"则不限--><maxSizeRollBackups value="20"/><!--日志格式--><layout type="log4net.Layout.PatternLayout"><param name="ConversionPattern" value="%n【%d】:%m%n【源码信息】:%location%n" /></layout><!--限制只写信息日志--><filter type="log4net.Filter.LevelRangeFilter"><param name="LevelMin" value="WARN" /><param name="LevelMax" value="WARN" /></filter></appender><appender name="AdminLogFileAppender_Error" type="log4net.Appender.RollingFileAppender"><!--多线程时采用最小锁定:记录日志写入文件时,不锁定文本文件,防止多线程时不能写Log,官方说线程非安全--><lockingModel type="log4net.Appender.FileAppender+MinimalLock"/><!-- 不自动生成空白文件 --><lockingModel type="Common.Helper.MinimalLockDeleteEmpty"/><!--目录路径,可以是相对路径或绝对路径--><param name="File" value="log\\Error\\"/><!--文件名,按日期生成文件夹--><param name="DatePattern" value="/yyyy-MM/&quot;Error_&quot;MM-dd-HH&quot;.log&quot;"/><!--追加到文件--><appendToFile value="true"/><!--创建日志文件的方式,可选值:Date[日期],文件大小[Size],混合[Composite]--><rollingStyle value="Composite"/><preserveLogFileNameExtension value="true"/><!--写到一个文件--><staticLogFileName value="false"/><!--单个文件大小。单位:KB|MB|GB--><maximumFileSize value="5MB"/><!--最多保留的文件数,设为"-1"则不限--><maxSizeRollBackups value="20"/><!--日志格式--><layout type="log4net.Layout.PatternLayout"><param name="ConversionPattern" value="%n【%d】:%m%n【源码信息】:%location%n" /></layout><!--限制只写信息日志--><filter type="log4net.Filter.LevelRangeFilter"><param name="LevelMin" value="ERROR" /><param name="LevelMax" value="ERROR" /></filter></appender><appender name="AdminLogFileAppender_Fatal" type="log4net.Appender.RollingFileAppender"><!--多线程时采用最小锁定:记录日志写入文件时,不锁定文本文件,防止多线程时不能写Log,官方说线程非安全--><lockingModel type="log4net.Appender.FileAppender+MinimalLock"/><!-- 不自动生成空白文件 --><lockingModel type="Common.Helper.MinimalLockDeleteEmpty"/><!--目录路径,可以是相对路径或绝对路径--><param name="File" value="log\\Fatal\\"/><!--文件名,按日期生成文件夹--><param name="DatePattern" value="/yyyy-MM/&quot;Fatal_&quot;MM-dd-HH&quot;.log&quot;"/><!--追加到文件--><appendToFile value="true"/><!--创建日志文件的方式,可选值:Date[日期],文件大小[Size],混合[Composite]--><rollingStyle value="Composite"/><preserveLogFileNameExtension value="true"/><!--写到一个文件--><staticLogFileName value="false"/><!--单个文件大小。单位:KB|MB|GB--><maximumFileSize value="5MB"/><!--最多保留的文件数,设为"-1"则不限--><maxSizeRollBackups value="20"/><!--日志格式--><layout type="log4net.Layout.PatternLayout"><param name="ConversionPattern" value="%n【%d】:%m%n【源码信息】:%location%n" /></layout><!--限制只写信息日志--><filter type="log4net.Filter.LevelRangeFilter"><param name="LevelMin" value="FATAL" /><param name="LevelMax" value="FATAL" /></filter></appender><!-- Admin_Ex_File管理员权限的异常日志 --><appender name="AdminLogFileAppender_Ex_Error" type="log4net.Appender.RollingFileAppender"><!--多线程时采用最小锁定:记录日志写入文件时,不锁定文本文件,防止多线程时不能写Log,官方说线程非安全--><lockingModel type="log4net.Appender.FileAppender+MinimalLock"/><!-- 不自动生成空白文件 --><lockingModel type="Common.Helper.MinimalLockDeleteEmpty"/><!--目录路径,可以是相对路径或绝对路径--><param name="File" value="log\\Error\\"/><!--文件名,按日期生成文件夹--><param name="DatePattern" value="/yyyy-MM/&quot;Error_&quot;MM-dd-HH&quot;.log&quot;"/><!--追加到文件--><appendToFile value="true"/><!--创建日志文件的方式,可选值:Date[日期],文件大小[Size],混合[Composite]--><rollingStyle value="Composite"/><preserveLogFileNameExtension value="true"/><!--写到一个文件--><staticLogFileName value="false"/><!--单个文件大小。单位:KB|MB|GB--><maximumFileSize value="5MB"/><!--最多保留的文件数,设为"-1"则不限--><maxSizeRollBackups value="20"/><!--日志格式--><layout type="log4net.Layout.PatternLayout"><param name="ConversionPattern" value="%n【%d】:%m%n【源码信息】:%location%n【异常信息】:%exception%n" /></layout><!--限制只写信息日志--><filter type="log4net.Filter.LevelRangeFilter"><param name="LevelMin" value="ERROR" /><param name="LevelMax" value="ERROR" /></filter></appender><appender name="AdminLogFileAppender_Ex_Fatal" type="log4net.Appender.RollingFileAppender"><!--多线程时采用最小锁定:记录日志写入文件时,不锁定文本文件,防止多线程时不能写Log,官方说线程非安全--><lockingModel type="log4net.Appender.FileAppender+MinimalLock"/><!-- 不自动生成空白文件 --><lockingModel type="Common.Helper.MinimalLockDeleteEmpty"/><!--目录路径,可以是相对路径或绝对路径--><param name="File" value="log\\Fatal\\"/><!--文件名,按日期生成文件夹--><param name="DatePattern" value="/yyyy-MM/&quot;Fatal_&quot;MM-dd-HH&quot;.log&quot;"/><!--追加到文件--><appendToFile value="true"/><!--创建日志文件的方式,可选值:Date[日期],文件大小[Size],混合[Composite]--><rollingStyle value="Composite"/><preserveLogFileNameExtension value="true"/><!--写到一个文件--><staticLogFileName value="false"/><!--单个文件大小。单位:KB|MB|GB--><maximumFileSize value="5MB"/><!--最多保留的文件数,设为"-1"则不限--><maxSizeRollBackups value="20"/><!--日志格式--><layout type="log4net.Layout.PatternLayout"><param name="ConversionPattern" value="%n【%d】:%m%n【源码信息】:%location%n【异常信息】:%exception%n" /></layout><!--限制只写信息日志--><filter type="log4net.Filter.LevelRangeFilter"><param name="LevelMin" value="FATAL" /><param name="LevelMax" value="FATAL" /></filter></appender><!-- 将日志输出到控制台 --><appender name="ConsoleAppender"  type="log4net.Appender.ConsoleAppender" ><layout type="log4net.Layout.PatternLayout"><param name="ConversionPattern"  value="%n【[%5p][%d]】=> %m%n" /></layout><filter type="log4net.Filter.LevelRangeFilter"><param name="LevelMin" value="INFO" /><param name="LevelMax" value="WARN" /></filter></appender><!-- 控制台异常日志 --><appender name="ConsoleAppender_Ex"  type="log4net.Appender.ConsoleAppender" ><layout type="log4net.Layout.PatternLayout"><param name="ConversionPattern"  value="%n【[%5p][%d]】=> %m%n【异常信息】:%exception%n" /></layout><filter type="log4net.Filter.LevelRangeFilter"><param name="LevelMin" value="ERROR" /><param name="LevelMax" value="FATAL" /></filter></appender><!-- 控制台颜色日志 --><appender name="ColoredConsoleAppender"  type="log4net.Appender.ColoredConsoleAppender" ><mapping><level value="WARN" /><foreColor value="Yellow" /></mapping><layout type="log4net.Layout.PatternLayout"><param name="ConversionPattern"  value="%n【[%5p][%d]】=> %m%n" /></layout><filter type="log4net.Filter.LevelRangeFilter"><param name="LevelMin" value="INFO" /><param name="LevelMax" value="WARN" /></filter></appender><!-- 控制台颜色异常日志 --><appender name="ColoredConsoleAppender_Ex"  type="log4net.Appender.ColoredConsoleAppender" ><mapping><level value="FATAL" /><foreColor value="White" /><backColor value="Red" /></mapping><mapping><level value="ERROR" /><foreColor value="Red" /></mapping><layout type="log4net.Layout.PatternLayout"><param name="ConversionPattern"  value="%n【[%5p][%d]】=> %m%n【异常信息】:%exception%n" /></layout><filter type="log4net.Filter.LevelRangeFilter"><param name="LevelMin" value="ERROR" /><param name="LevelMax" value="FATAL" /></filter></appender><!-- 将日志写入到数据库 --><appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender"><!--BufferSize为缓冲区大小,只有日志记录达到设定值才会一块写入到数据库--><bufferSize value="1" /><!--postgresql需要的客户端控件--><connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /><connectionString value="Data Source=.;Initial Catalog=DataCow;Integrated Security=True" /><commandText value="insert into [UserLog]([LogKindID],[Operator],[LogContent]) values(@LogKindID,@Operator,@LogContent)" /><parameter><parameterName value="@LogKindID" /><dbType value="Int32" /><layout type="Common.Helper.MyLayout" ><conversionPattern value="%property{LogKindID}" /></layout></parameter><parameter><parameterName value="@Operator" /><dbType value="Int32" /><layout type="Common.Helper.MyLayout"><conversionPattern value="%property{Operator}" /></layout></parameter><parameter><parameterName value="@LogContent" /><dbType value="String" /><!--长度不可以省略,否则不会输出--><size value="2000000000" /><layout type="Common.Helper.MyLayout"><conversionPattern value="%property{LogContent}" /></layout></parameter><filter type="log4net.Filter.LevelRangeFilter"><param name="LevelMin" value="INFO" /><param name="LevelMax" value="INFO" /></filter></appender></log4net>
</configuration>

其中,你要知道几个重要的标签<log4net>、<root>、<logger>、<level>、<appender-ref>、<appender>:
其中配置几乎全写在<log4net>标签下;
<root>标签可以解读为全局配置;
<logger>可以理解为子类,继承<root>;
<appender-ref>是<appender>的关联桥梁,类似数据表的外键;
<appender>日志类型的详细配置在这里完成,最难配也是最复杂的一个标签;
上面标签具体什么应用,我配置文件上有写,并且可以看这篇大佬的博文
上面大佬博文也有配置参数(<layout>标签下的参数,仅支持此标签:%d、%m、%n、%location、%exception等)的使用,我就不写了,大家好好看那篇博文;

其中,我要讲的一些配置坑:
(1)数据库配置标签下的<parameter><dbType value=“String” />,这个数据类型,你要明白dbType数据类型、数据库数据类型与C#数据类型是怎么一一对应的(自己百度,或者直接看我参考的大佬的博文1,大佬的博文2)

(2)log4net日志框架每次都会生成很多配置的空白文件,为了不自动生成空白文件,我加了这个标签 <lockingModel type=“Common.Helper.MinimalLockDeleteEmpty”/>其中,Common.Helper.MinimalLockDeleteEmpty是我自己封装的log4net帮助类。

	/// <summary>/// 避免生成空白文件/// </summary>public class MinimalLockDeleteEmpty : FileAppender.MinimalLock{public override void ReleaseLock(){base.ReleaseLock();var logFile = new FileInfo(CurrentAppender.File);if (logFile.Exists && logFile.Length <= 0){logFile.Delete();}}}

(3)配数据库的不能乱改,要不会出很多问题,其中下面的不能乱配,要知道怎么配

<!--这个就别乱改了,我之前改了就写入不了-->
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<!--这个就是常规的数据配置,不懂得,可以参考一下步骤:
1、用vs的工具,连接到数据库;
2、	点击数据名称,右下角会出现数据库的属性框;
3、选择“连接字符串”,复制值进行粘贴;
-->
<connectionString value="Data Source=.;Initial Catalog=DataCow;Integrated Security=True" />

2、程序配置文件

(1)配置日志调试文件: 配置过Log4net的同学都知道,内部的一些报错很难排查原因,所以,开发为了更加方便,我们一般要在开发前,将项目的配置文件配下,从而记录log4net的运行日志(记录在:Log4Net_Debug.txt文件)。我在Web.config文件下配置的,下面代码不是全部代码,直接将注释下的标签代码复制到自己项目的配置文件,千万不要直接复制粘贴,懂得都懂,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<!--For more information on how to configure your ASP.NET application, please visithttps://go.microsoft.com/fwlink/?LinkId=301880-->
<configuration><appSettings><!-- log4Net的运行Debug日志,log4net框架开发完毕可删除 --><add key="log4net.Internal.Debug" value="true"/></appSettings><!-- log4Net的运行Debug日志,log4net框架开发完毕可删除 --><<system.diagnostics><trace autoflush="true"><listeners><addname="textWriterTraceListener"type="System.Diagnostics.TextWriterTraceListener"initializeData="log\Debug\Log4Net_Debug.txt" /></listeners></trace></system.diagnostics>
</configuration>

(2)全局配置:在公共模块下的AssemblyInfo.cs类,加入下面代码:
在这里插入图片描述

//log4net框架配置
/** XmlConfiguratorAttribute
The log4net.Config.XmlConfiguratorAttribute Allows the XmlConfigurator to be configured using the following properties:ConfigFile
If specified, this is the filename of the configuration file to use with the XmlConfigurator. This file path is relative to the application base directory (AppDomain.CurrentDomain.BaseDirectory).This property cannot be used in conjunction with the ConfigFileExtension property.ConfigFileExtension
If specified, this is the extension for the configuration file. The assembly file name is used as the base name with the this extension appended. For example if the assembly is loaded from the a file TestApp.exe and the ConfigFileExtension property is set to log4net then the configuration file name is TestApp.exe.log4net. This is equivalent to setting the ConfigFile property to TestApp.exe.log4net.The path to the configuration file is build by using the application base directory (AppDomain.CurrentDomain.BaseDirectory), the assembly file name and the configuration file extension.This property cannot be used in conjunction with the ConfigFile property.Watch
If this flag is specified and set to true then the framework will watch the configuration file and will reload the config each time the file is modified.If neither of the ConfigFile or ConfigFileExtension properties are specified, the application configuration file (e.g. TestApp.exe.config) will be used as the log4net configuration file.*/
[assembly: log4net.Config.XmlConfigurator(Watch = true, ConfigFile = "log4Net.config")] // 指定读取log4net 的配置文件

(3)log4Net.config文件放的位置: 这个文件不能乱放,一定要放对位置,当然,假如你直接将配置信息写到项目文件配置文件下,那就跟我的有点不一样了,我是独立出来的,这样比较好管理。这配置文件一定要放到项目启动项的下面,比如,webforme,mvc程序,直接放Web.config的同级目录,控制台程序,要放在 **.exe文件下面,一般在项目的Debug文件夹下。

3、日志帮助类的编写

经过以上,项目里应该差不多配置好了,接下来就要写日志帮助类了,这样才能正常调用并正常实现自己所需要的日志逻辑功能,下面我全部的日志帮助类代码:
帮助类:

using Common.Models;
using log4net;
using log4net.Appender;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;namespace Common.Helper
{/// <summary>/// 对应log4Net.config文件logger的name属性/// </summary>public enum log4NetConfigEnum{//文件日志Default_File=1,             //默认文件日志Default_Ex_File,            //默认文件异常日志Admin_File,                 //管理员权限文件日志Admin_Ex_File,              //管理员权限异常文件日志//控制台日志ConsoleDefault,                    //默认控制台日志ConsoleDefault_Ex,                 //控制台异常日志ColoredConsoleDefault,              //有颜色的控制台日志ColoredConsoleDefault_Ex,            //有颜色的控制台异常日志//Sql日志DefaultLog_Sql                  //默认Sql数据库日志}/// <summary>/// 避免生成空白文件/// </summary>public class MinimalLockDeleteEmpty : FileAppender.MinimalLock{public override void ReleaseLock(){base.ReleaseLock();var logFile = new FileInfo(CurrentAppender.File);if (logFile.Exists && logFile.Length <= 0){logFile.Delete();   }}}public abstract class ILogHelper<T> where T:class{#region Log4Netpublic static ILog iLog { get; set; } = GetLogConfig<T>();public static void Debug(LogModel logModel){if (!iLog.IsDebugEnabled|| logModel==null)return;var ex = logModel.exception;var msg = logModel.LogContent;if (ex == null){iLog.Debug(msg);}else{iLog.Debug(msg, ex);}}public static void Info(LogModel logModel){if (!iLog.IsInfoEnabled || logModel == null)return;var ex = logModel.exception;var msg = logModel.LogContent;if (ex == null){iLog.Info(msg);}else{iLog.Info(msg, ex);}}public static void Error(LogModel logModel){if (!iLog.IsErrorEnabled || logModel == null)return;var ex = logModel.exception;var msg = logModel.LogContent;if (ex == null){iLog.Error(msg);}else{iLog.Error(msg, ex);}}public static void Fatal(LogModel logModel){if (!iLog.IsFatalEnabled || logModel == null)return;var ex = logModel.exception;var msg = logModel.LogContent;if (ex == null){iLog.Fatal(msg);}else{iLog.Fatal(msg, ex);}}public static void Warn(LogModel logModel){if (!iLog.IsWarnEnabled || logModel == null)return;var ex = logModel.exception;var msg = logModel.LogContent;if (ex == null){iLog.Warn(msg);}else{iLog.Warn(msg, ex);}}public static ILog GetLogConfig<T>(){var t = (T)Activator.CreateInstance(typeof(T));System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(t.GetType().TypeHandle);return iLog;}#endregion}#region 文件日志帮助类public class DefaultFileLogHelper : ILogHelper<DefaultFileLogHelper>{static DefaultFileLogHelper(){ILogHelper<DefaultFileLogHelper>.iLog = LogManager.GetLogger(log4NetConfigEnum.Default_File.ToString());}}public class FileExceptionLogHelper : ILogHelper<FileExceptionLogHelper>{static FileExceptionLogHelper(){ILogHelper<FileExceptionLogHelper>.iLog = LogManager.GetLogger(log4NetConfigEnum.Default_Ex_File.ToString());}}public class AdminFileLogHelper : ILogHelper<AdminFileLogHelper>{static AdminFileLogHelper(){ILogHelper<AdminFileLogHelper>.iLog = LogManager.GetLogger(log4NetConfigEnum.Admin_File.ToString());}}public class AdminExceptionFileLogHelper : ILogHelper<AdminExceptionFileLogHelper>{static AdminExceptionFileLogHelper(){ILogHelper<AdminExceptionFileLogHelper>.iLog = LogManager.GetLogger(log4NetConfigEnum.Admin_Ex_File.ToString());}}#endregion#region 数据库日志帮助类public class SqlLogHelper : log4net.Layout.PatternLayout{public static ILog iLog = LogManager.GetLogger(log4NetConfigEnum.DefaultLog_Sql.ToString());public SqlLogHelper()=> new MyLayout();public static Boolean Info(LogModel logModel){if (!iLog.IsInfoEnabled || logModel == null)return false;System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(new SqlLogHelper().GetType().TypeHandle);iLog.Info(logModel);return true;}}public class MyLayout : log4net.Layout.PatternLayout{public MyLayout(){this.AddConverter("property", typeof(PropertyPatternConverter));}}public class PropertyPatternConverter : log4net.Layout.Pattern.PatternLayoutConverter{protected override void Convert(System.IO.TextWriter writer, log4net.Core.LoggingEvent loggingEvent){if (Option != null){// Write the value for the specified keyWriteObject(writer, loggingEvent.Repository, LookupProperty(Option, loggingEvent));}else{// Write all the key value pairsWriteDictionary(writer, loggingEvent.Repository, loggingEvent.GetProperties());}}/// <summary>/// 通过反射获取传入的日志对象的某个属性的值/// </summary>/// <param name="property"></param>/// <returns></returns>private object LookupProperty(string property, log4net.Core.LoggingEvent loggingEvent){object propertyValue = string.Empty;PropertyInfo propertyInfo = loggingEvent.MessageObject.GetType().GetProperty(property);if (propertyInfo != null)propertyValue = propertyInfo.GetValue(loggingEvent.MessageObject, null);return propertyValue;}}#endregion#region 控制台日志帮助类public class ConsoleLogHelper : ILogHelper<ConsoleLogHelper>{static ConsoleLogHelper(){ILogHelper<ConsoleLogHelper>.iLog = LogManager.GetLogger(log4NetConfigEnum.ConsoleDefault.ToString());}}public class ConsoleExceptionLogHelper : ILogHelper<ConsoleExceptionLogHelper>{static ConsoleExceptionLogHelper(){ILogHelper<ConsoleExceptionLogHelper>.iLog = LogManager.GetLogger(log4NetConfigEnum.ConsoleDefault_Ex.ToString());}}public class ColoredConsoleLogHelper : ILogHelper<ColoredConsoleLogHelper>{static ColoredConsoleLogHelper(){ILogHelper<ColoredConsoleLogHelper>.iLog = LogManager.GetLogger(log4NetConfigEnum.ColoredConsoleDefault.ToString());}}public class ColoredConsoleExceptionLogHelper : ILogHelper<ColoredConsoleExceptionLogHelper>{static ColoredConsoleExceptionLogHelper(){ILogHelper<ColoredConsoleExceptionLogHelper>.iLog = LogManager.GetLogger(log4NetConfigEnum.ColoredConsoleDefault_Ex.ToString());}}#endregion
}

Model类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace Common.Models
{public class LogModel{public long ID { get; set; }public int LogKindID { get; set; }public int Operator { get; set; }public string LogContent { get; set; }public DateTime AddTime { get; set; }public Exception exception { get; set; } = null;}
}

代码疑点难点
(1)动态加载子类参数: 一般地,子类不能正常传参数给父类,并且最重要的是,上面帮助类用到的全是静态变量和方法,这个才是阻碍传参最麻烦的,这里就要用到相应的一个动态构造的方法,这样才能实现这个特殊功能,方法是在父类下,执行一个方法,并且让子类执行静态构造函数,给静态变量赋值。
(2)数据库的自定义字段配置: 绝大部分,写入数据库都要用到自定义字段,所以这个是必须要配的,不配的话就写入不了。
(3)配置文件下logger对应: LogManager.GetLogger(name),name是logger定义好的的name属性值。

通过上面步骤,已经全部配置好了,通过测试后,注释掉Web.config文件下的log4net日志配置就好。


http://chatgpt.dhexx.cn/article/3f296P8r.shtml

相关文章

Log4Net详解

Log4Net详解 零、文章目录 一、Log4Net详解 1、功能概述 &#xff08;1&#xff09;概述 Log4net库是.Net下一个非常优秀的开源日志记录组件&#xff0c;是一个帮助程序员将日志信息输出到各种目标&#xff08;控制台、文件、数据库等&#xff09;的工具。如果应用程序出现…

C#【必备技能篇】log4net的使用

使用log4net大致分以下几步&#xff1a; 1.安装 log4net&#xff0c;通过 Nuget 下载&#xff08;或者有log4net.dll的话&#xff0c;直接引用即可&#xff09; 2.新建 log4net.config 配置文件 <?xml version"1.0" encoding"utf-8" ?> <con…

Oracle存储过程的简单举例

一、建立测试数据 --建立测试数据: create table person(编号 number(10),姓名 varchar2(20),密码 varchar2(20));insert into person values(1,xzw,888);select * from person; 查询结果如下&#xff1a; 二、建立存储过程 --建立存储过程: create or replace procedure qu…

Mysql 存储过程案例教程

关注微信公共号&#xff1a;小程在线 关注CSDN博客&#xff1a;程志伟的博客 一、无参数无返回值存储过程 DELIMITER表示自定义结束符号&#xff0c;SQL一般默认&#xff1b;为结束符号 红色部分为固定格式 下面的查询语句&#xff0c;可以改成任意复杂的SQL语句 DELIMITE…

Oracle存储过程入门教程(通俗理解存储过程)

Oracle存储过程入门通俗介绍 一、118个真实应用场景的Oracle存储过程案例及开发指南二、存储过程通俗理解三、创建存储过程基本语法(汇总)四、执行存储过程的方式&#xff08;5种&#xff09;五、网上现有的创建存储过程的两种方式解释&#xff08;看注释&#xff09;六、一些存…

MySQL存储过程示例

实例1&#xff1a; 为了演示MySQL中的存储过程&#xff0c;我们先创建一些表和数据&#xff1a; drop table if exists my_test_table; create table my_test_table (id integer primary key not null AUTO_INCREMENT,name varchar(20),age integer,point double ); insert int…

mysql 存储过程详解

前言 在项目开发中&#xff0c;经常会遇到这样一种场景&#xff0c;当修改A表的一条数据时&#xff0c;需要关联修改B表、C表甚至其他更多表的数据&#xff0c;为什么会这样呢&#xff1f; 在真实的业务场景中&#xff0c;往往一张表的数据关联的业务是多样的&#xff0c;举例…

mysql存储过程call_mysql call 存储过程

PHP调用MYSQL存储过程实例 PHP调用MYSQL存储过程实例 标签&#xff1a; mysql存储phpsqlquerycmd 2010-09-26 11:10 11552人阅读 评论(3) 收藏 举报 实例一&#xff1a;无参的存储过程$conn mysql_connect(localhost,root,root) o... 文章 thinkyoung 2016-01-20 544浏览量 存…

ORACLE存储过程

oracle存储过程 目录 oracle存储过程 一.什么是存储过程 二.为什么要写存储过程 三.存储过程基础 1.存储过程结构 2.存储过程语法 3.pl/sql处理存储过程 4.案例实战 四.存储过程进阶 1.BUIK COLLECT 2.FORALL 3.pl/sql调试存储过程 4.案例实战 附.参考资料 一.什…

Greenplum创建存储过程

1.美图 1.对比 greenplum 的plpgsql 注意: greenplum 的plpgsql 与 postgresql 不是完全兼容的。plpgsql 不明确界定 函数和存储过程&#xff0c;“returns void” 表示 存储过程&#xff0c;“return 数据类型” 表示 函数。greenplum中的函数分成3种类型: immutable(不可变…

Mysql 创建存储过程和函数及各种例子

Mysql 创建存储过程和函数及各种例子 1. Mysql 创建存储过程1.1 前言知识1.1.1 语法结构1.1.2 简单解释 1.2 创建存储过程入门例子1.2.1 无参存储过程1.2.1.1 不带变量1.2.1.2 带变量 1.2.2 有入参的存储过程1.2.3 有出参的存储过程1.2.4 有入参和存储的存储过程1.2.5 inout的存…

oracle 存储过程 实例 循环 给查询赋值 游标取值

CREATE OR REPLACE PROCEDURE p_updete_gs is --仅供参考 i_jdid varchar(32); i_ryid varchar(32); cursor cur is --游标 给查询赋值 select c.jdid jdid, t.ryid rybh from t_zcj_rctj t,t_zj_jd c where t.ryidc.rybh and t.bgzt<>3 and c.bgzt<>…

SQL存储过程实例详解

SQL存储过程实例详解 本文用3个题目&#xff0c;从建立数据库到创建存储过程&#xff0c;详细讲解数据库的功能。 题目1 学校图书馆借书信息管理系统建立三个表&#xff1a; 学生信息表&#xff1a;student 字段名称 数据类型 说明 stuID char(10) 学生编号&#xff0c;主…

oracle存储过程实例

认识存储过程和函数 存储过程和函数也是一种PL/SQL块&#xff0c;是存入数据库的PL/SQL块。但存储过程和函数不同于已经介绍过的PL/SQL程序&#xff0c;我们通常把PL/SQL程序称为无名块&#xff0c;而存储过程和函数是以命名的方式存储于数据库中的。和PL/SQL程序相比&#xff…

MySQL存储过程实例

1、简单实例 create procedure demo.p_test1() begin-- 使用 declare语句声明一个变量declare id int default 0;declare name varchar(50) default ;-- 使用set语句给变量赋值set id7521;-- 将users表中id1的名称赋值给usernameselect ename into name from demo.emp where e…

存储过程详解与实例

存储过程 1、存储过程的优缺点 优点 通过把处理封装在容易使用的单元中&#xff0c;简化复杂的操作&#xff1b;简化对变动的管理&#xff1b;通常存储过程有助于提高应用程序的性能&#xff1b;存储过程有助于减少应用程序和数据库服务器之间的流量&#xff0c;因为应用程序…

数据库存储过程讲解与实例

目录 1 存储过程简介 2 存储过程使用 2.1 创建存储过程 2.2 in&#xff0c;out以及inout 1 存储过程简介 SQL语句需要先编译然后执行&#xff0c;而存储过程&#xff08;Stored Procedure&#xff09;是一组为了完成特定功能的SQL语句集&#xff0c;经编译后存储在数据库中…

【数据库】ACID底层实现原理

前言 我们在学MySQL的时候事务是必须要知道的部分&#xff0c;也就是原子性(Atomic)、一致性(Consistency)、隔离性(isolation)和持久性(Persistence)。知道他的概念其实是远远不够的&#xff0c;现在越来越卷&#xff0c;那么就必须知道的他的原理什么&#xff1f;怎么是实现…

数据库-ACID

ACID:原子性、持久性、一致性、独立性 事务的原子性(Atomicity)&#xff1a;是指一个事务要么全部执行&#xff0c;要么不执行&#xff0c;也就是说一个事务不可能只执行了一半就停止了。比如你从取款机取钱&#xff0c;这个事务可以分成两个步骤&#xff1a;1划卡&#xff0c;…

Mysql ACID详解

ACID简述 Atomicity、Durability实现之 &#xff08;WALredo log&#xff09; Atomicity 、Isolation实现之 &#xff08;锁 OR undo logMVCC&#xff09; 一、前言 主要是后台程序员都会和数据库打交道&#xff0c;最常用的关系型数据库是MySQL&#xff0c;最常用的存储引擎是…