MySQL 4.1.0 中文参考手册 --- 6.7 MySQL 事务与锁定命令

本文围绕 MySQL 4.1.0-alpha 版本,介绍了事务与锁定命令。包括事务模式设置、存储更改方式,以及不同表类型在事务中的表现。还阐述了表锁定的相关内容,如锁定权限、锁的类型及作用,以及事务隔离级的设置方法等。

MySQL Reference Manual for version 4.1.0-alpha.


6.7 MySQL 事务与锁定命令

6.7.1 BEGIN/COMMIT/ROLLBACK 句法

缺省的,MySQL 运行在 autocommit 模式。这就意味着,当你执行完一个更新时,MySQL 将立刻将更新存储到磁盘上。

如果你使用事务安全表 (例如 InnoDBBDB),通过下面的命令,你可以设置 MySQL 为非 autocommit 模式:

SET AUTOCOMMIT=0

在此之后,你必须使用 COMMIT 来存储你的更改到磁盘上,或者使用 ROLLBACK ,如果你希望忽略从你的事务开始所做的更改。

如果你希望为一系列语句从 AUTOCOMMIT 模式转换,你可以使用 START TRANSACTIONBEGINBEGIN WORK 语句:

START TRANSACTION;
SELECT @A:=SUM(salary) FROM table1 WHERE type=1;
UPDATE table2 SET summmary=@A WHERE type=1;
COMMIT;

START TRANSACTION 在 MySQL 4.0.11 中被加入;这是被推荐的开始一个特别(ad-hoc)事务的方式,因为这是 ANSI SQL 句法。

注意,如果你使用的是一个非事务安全表,更改会立刻被存储,不受 autocommit 模式状态的约束。

当你更新了一个非事务表后,如果你执行一个 ROLLBACK,你将得到一个错误 (ER_WARNING_NOT_COMPLETE_ROLLBACK) 作为一个警告。所有事务安全表将被恢复,但是非事务安全表将不会改变。

如果你使用 START TRANSACTIONSET AUTOCOMMIT=0,你应该使用 MySQL 二进制日志做备份以代替老的更新日志。事务处理被以一个大块形式存储在二进制日志中,在 COMMIT 上面,为了保护回滚的事务,而不是被存储的。查看章节 4.9.4 二进制日志。 如果您使用起动事务处理或集AUTOCOMMIT=0 ,您应该使用MySQL 二进制日志为备份代替更旧的更新日志。 事务处理存储在二进制登录一大块,做,保证, 滚的事务处理不存储。 参见部分4 。9.4 二进制日志。

下列命令自动的结束一个事务 (就好像你在执行这个命令之前,做了一个 COMMIT):

命令 命令 命令
ALTER TABLE BEGIN CREATE INDEX
DROP DATABASE DROP TABLE RENAME TABLE
TRUNCATE    

你可以使用 SET TRANSACTION ISOLATION LEVEL ... 改变事务的隔离级。查看章节 6.7.3 SET TRANSACTION 句法

6.7.2 LOCK TABLES/UNLOCK TABLES 句法

LOCK TABLES tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE}
            [, tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE} ...]
...
UNLOCK TABLES

LOCK TABLES 为当前线程锁定表。UNLOCK TABLES 释放当前线程拥有的所有锁定。当线程发出另一个 LOCK TABLES,或当与服务器的连接被关闭时,被当前线程锁定的所有表将被自动地解锁。

为了在 MySQL 4.0.2 使用 LOCK TABLES ,你必须拥有一个全局的 LOCK TABLES 权限和一个在相关表上的 SELECT 权限。在 MySQL 3.23 中,你对该表需要有 SELECTinsertDELETEUPDATE 权限。

使用 LOCK TABLES 的主要原因是,仿效事务处理或在更新表时得到更快的速度。此后会有更详细的描述。

如果一个线程在一个表上得到一个 READ 锁,该线程 (和所有其它线程) 只能从表中读取。如果一个线程在一个表上得到一个 WRITE 锁,那么只有拥有这个锁的线程可以从表中读取和写表。其它的线程被阻塞。

READ LOCALREAD 之间的不同就在于,当锁被加载时,READ LOCAL 允许非冲突(non-conflicting) INSERT 语句执行。如果当你加载着锁时从 MySQL 外部操作数据库文件,这将仍不能被使用。

当你使用 LOCK TABLES 是地,你必须锁定所有你将使用的表,并且必须使用与你的查询中将使用的别名相同!如果你在一个查询中多次使用一个表(用别名),你必须为每一个别名获得一个锁。

WRITE 锁通过比 READ 锁有更高的权限,以确保更新被尽快地处理。这就意味着,如果一个线程获得一个 READ 锁,而同时另外一个线程请求一个 WRITE 锁,并发的 READ 锁请求将等待直到 WRITE 线程得到了锁并释放了它。你可以使用 LOW_PRIORITY WRITE 锁,当该线程在等待 WRITE 锁时,它将允许其它的线程获得 READ 锁。 你应该只使用 LOW_PRIORITY WRITE 锁,如果你确信这将是最后一次,当没有线程将拥有 READ 锁。

LOCK TABLES 工作如下:

  1. 以内部定义的次序排序所有被锁定的表 (从用户立场说,该次序是不明确的)。
  2. 如果一个表被以一个读锁和一个写锁锁定,将写锁放在读锁之前。
  3. 一次只锁定一个表,只到线程得到所有的锁定。

这个方案是为了确保,表锁定死锁释放。 对于这个模式你仍然有些其它事情需要知道:

如果你对一个表使用一个 LOW_PRIORITY WRITE 锁定,这就意味着,MySQL 将等待这个锁,直到没有线程请求一个 READ 锁。当线程得到了 WRITE 锁,并等待获得锁定表列表中的下一个表的锁定时,其它所有的线程将等待 WRITE 锁被释放。如果这在你的应用程序中会引起一个严重的问题,你应该考虑将你的某些表转换为事务安全表。

你可以使用 KILL 安全地杀死一个正在表锁定的线程。查看章节 4.5.5 KILL 句法

注意,你不应该 锁定你正在对其使用 INSERT DELAYED 的表。这是因为,在这种情况下,INSERT 是通过单独的线程完成的。

通常,你不需要锁定任何表,因为所有单 UPDATE 语句都是原子的;其它的线程无法干扰当前执行的 SQL 语句。当你无论如何希望锁定表时,这里有一些情况:

  • 如果你在一束表上运行许多操作,锁定你将要使用的表,这会更快一些。当然有不利的方面,其它线程将不能更新一个 READ 锁的表,并且没有其它线程要以读取一个 WRITE 锁的表。 在 LOCK TABLES 下,某些事运行得更快一些的原因是,MySQL 将不会转储清除被锁定表键高速缓冲,直到 UNLOCK TABLES 被调用 (通常键高速缓冲在每个 SQL 语句后都会被转储清除)。这将加速在 MyISAM 表上的插入、更新、删除。

  • 如果你在 MySQL 中正在使用一个不支持事务的存储引擎,如果你希望能确保没有其它的线程会出现在一个 SELECT 和 一个 UPDATE 之间,你必须使用 LOCK TABLES 。下面的示例显示为了安全地执行,这里需要LOCK TABLES
    mysql> LOCK TABLES trans READ, customer WRITE;
    mysql> SELECT SUM(value) FROM trans WHERE customer_id=some_id;
    mysql> UPDATE customer SET total_value=sum_from_previous_statement
        ->        WHERE customer_id=some_id;
    mysql> UNLOCK TABLES;
    
    不使用 LOCK TABLES,将可能发生在 SELECTUPDATE 语句执行期间有另外一个线程可能在 trans 表中插入一行新记录。

通过使用递增更新 (UPDATE customer SET value=value+new_value) 或 LAST_INSERT_ID() 函数,你可以在很多情况下避免使用 LOCK TABLES

你也可以使用用户级锁定函数 GET_LOCK()RELEASE_LOCK() 解决一些情况,这些锁被保存在服务器上的一个哈希表中,并以 pthread_mutex_lock()pthread_mutex_unlock() 实现以获得高速度。查看章节 6.3.6.2 辅助功能函数

查看章节 5.3.1 MySQL 如何锁定表,以获取关于锁定方案的更多信息。

你可以使用 FLUSH TABLES WITH READ LOCK 命令以读锁锁定所有数据库中的所有表。查看章节 4.5.3 FLUSH 句法。如果你有一个可以及时建立文件快照的文件系统,例如 Veritas,这将是得到备份的非常方便方式。

注意:LOCK TABLES 不是事务安全的,在尝试锁定一个表之前,将自动地提交所有的活动事务。

6.7.3 SET TRANSACTION 句法

SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL
{ READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }

设置全局的、整个会话或下一个事务的事务隔离级。

缺省行为是设置下一个(未启动的)事务的隔离级。如果你使用 GLOBAL 关键词,语句为所有在那个点上建立的新连接设置默认的全局事务隔离级。为了这样做,你需要有 SUPER 权限。使用 SESSION 关键词为当前连接所有将来执行的事务设置默认的事务隔离级。

你可以使用 --transaction-isolation=...mysqld 设置默认的全局隔离级。查看章节 4.1.1 mysqld 命令行选项

 

conda_env.txt的内容是# This file may be used to create an environment using: # $ conda create --name <env> --file <this file> # platform: linux-64 _libgcc_mutex=0.1=main _openmp_mutex=5.1=1_gnu alabaster=0.7.12=pyhd3eb1b0_0 arrow=1.2.3=py312h06a4308_1 astroid=2.14.2=py312h06a4308_0 asttokens=2.0.5=pyhd3eb1b0_0 atomicwrites=1.4.0=py_0 attrs=23.1.0=py312h06a4308_0 autopep8=2.0.4=pyhd3eb1b0_0 babel=2.11.0=py312h06a4308_0 beautifulsoup4=4.12.2=py312h06a4308_0 binaryornot=0.4.4=pyhd3eb1b0_1 black=24.3.0=py312h06a4308_0 blas=1.0=mkl bleach=4.1.0=pyhd3eb1b0_0 brotli=1.0.9=h5eee18b_8 brotli-bin=1.0.9=h5eee18b_8 brotli-python=1.0.9=py312h6a678d5_8 bzip2=1.0.8=h5eee18b_6 ca-certificates=2024.3.11=h06a4308_0 certifi=2024.2.2=py312h06a4308_0 cffi=1.16.0=py312h5eee18b_1 chardet=4.0.0=py312h06a4308_1003 charset-normalizer=2.0.4=pyhd3eb1b0_0 click=8.1.7=py312h06a4308_0 cloudpickle=2.2.1=py312h06a4308_0 colorama=0.4.6=py312h06a4308_0 comm=0.2.1=py312h06a4308_0 contourpy=1.2.0=py312hdb19cb5_0 cookiecutter=2.6.0=py312h06a4308_0 cryptography=42.0.5=py312hdda0065_0 cuda-cudart=11.8.89=0 cuda-cupti=11.8.87=0 cuda-libraries=11.8.0=0 cuda-nvcc=12.4.131=0 cuda-nvrtc=11.8.89=0 cuda-nvtx=11.8.86=0 cuda-runtime=11.8.0=0 cudatoolkit=11.8.0=h6a678d5_0 cycler=0.11.0=pyhd3eb1b0_0 cyrus-sasl=2.1.28=h52b45da_1 dbus=1.13.18=hb2f20db_0 debugpy=1.6.7=py312h6a678d5_0 decorator=5.1.1=pyhd3eb1b0_0 defusedxml=0.7.1=pyhd3eb1b0_0 diff-match-patch=20200713=pyhd3eb1b0_0 dill=0.3.7=py312h06a4308_0 docstring-to-markdown=0.11=py312h06a4308_0 docutils=0.18.1=py312h06a4308_3 executing=0.8.3=pyhd3eb1b0_0 expat=2.6.2=h6a678d5_0 ffmpeg=4.3=hf484d3e_0 filelock=3.13.1=py312h06a4308_0 flake8=7.0.0=py312h06a4308_0 fontconfig=2.14.1=h4c34cd2_2 fonttools=4.51.0=py312h5eee18b_0 freetype=2.12.1=h4a9f257_0 glib=2.78.4=h6a678d5_0 glib-tools=2.78.4=h6a678d5_0 gmp=6.2.1=h295c915_3 gnutls=3.6.15=he1e5248_0 gst-plugins-base=1.14.1=h6a678d5_1 gstreamer=1.14.1=h5eee18b_1 icu=73.1=h6a678d5_0 idna=3.7=py312h06a4308_0 imagesize=1.4.1=py312h06a4308_0 importlib-metadata=7.0.1=py312h06a4308_0 inflection=0.5.1=py312h06a4308_1 intel-openmp=2023.1.0=hdb19cb5_46306 intervaltree=3.1.0=pyhd3eb1b0_0 ipykernel=6.28.0=py312h06a4308_0 ipython=8.20.0=py312h06a4308_0 isort=5.9.3=pyhd3eb1b0_0 jaraco.classes=3.2.1=pyhd3eb1b0_0 jedi=0.18.1=py312h06a4308_1 jeepney=0.7.1=pyhd3eb1b0_0 jellyfish=1.0.1=py312hb02cf49_0 jinja2=3.1.3=py312h06a4308_0 jpeg=9e=h5eee18b_1 jsonschema=4.19.2=py312h06a4308_0 jsonschema-specifications=2023.7.1=py312h06a4308_0 jupyter_client=8.6.0=py312h06a4308_0 jupyter_core=5.5.0=py312h06a4308_0 jupyterlab_pygments=0.2.2=py312h06a4308_0 keyring=24.3.1=py312h06a4308_0 kiwisolver=1.4.4=py312h6a678d5_0 krb5=1.20.1=h143b758_1 lame=3.100=h7b6447c_0 lazy-object-proxy=1.10.0=py312h5eee18b_0 lcms2=2.12=h3be6417_0 ld_impl_linux-64=2.38=h1181459_1 lerc=3.0=h295c915_0 libbrotlicommon=1.0.9=h5eee18b_8 libbrotlidec=1.0.9=h5eee18b_8 libbrotlienc=1.0.9=h5eee18b_8 libclang=14.0.6=default_hc6dbbc7_1 libclang13=14.0.6=default_he11475f_1 libcublas=11.11.3.6=0 libcufft=10.9.0.58=0 libcufile=1.9.1.3=0 libcups=2.4.2=h2d74bed_1 libcurand=10.3.5.147=0 libcusolver=11.4.1.48=0 libcusparse=11.7.5.86=0 libdeflate=1.17=h5eee18b_1 libedit=3.1.20230828=h5eee18b_0 libevent=2.1.12=hdbd6064_1 libffi=3.4.4=h6a678d5_1 libgcc-ng=11.2.0=h1234567_1 libgfortran-ng=11.2.0=h00389a5_1 libgfortran5=11.2.0=h1234567_1 libglib=2.78.4=hdc74915_0 libgomp=11.2.0=h1234567_1 libiconv=1.16=h5eee18b_3 libidn2=2.3.4=h5eee18b_0 libjpeg-turbo=2.0.0=h9bf148f_0 libllvm14=14.0.6=hdb19cb5_3 libnpp=11.8.0.86=0 libnvjpeg=11.9.0.86=0 libpng=1.6.39=h5eee18b_0 libpq=12.17=hdbd6064_0 libsodium=1.0.18=h7b6447c_0 libspatialindex=1.9.3=h2531618_0 libstdcxx-ng=11.2.0=h1234567_1 libtasn1=4.19.0=h5eee18b_0 libtiff=4.5.1=h6a678d5_0 libunistring=0.9.10=h27cfd23_0 libuuid=1.41.5=h5eee18b_0 libwebp-base=1.3.2=h5eee18b_0 libxcb=1.15=h7f8727e_0 libxkbcommon=1.0.1=h5eee18b_1 libxml2=2.10.4=hfdd30dd_2 llvm-openmp=14.0.6=h9e868ea_0 lz4-c=1.9.4=h6a678d5_1 markdown-it-py=2.2.0=py312h06a4308_1 markupsafe=2.1.3=py312h5eee18b_0 matplotlib=3.8.4=py312h06a4308_0 matplotlib-base=3.8.4=py312h526ad5a_0 matplotlib-inline=0.1.6=py312h06a4308_0 mccabe=0.7.0=pyhd3eb1b0_0 mdurl=0.1.0=py312h06a4308_0 mistune=2.0.4=py312h06a4308_0 mkl=2023.1.0=h213fc3f_46344 mkl-service=2.4.0=py312h5eee18b_1 mkl_fft=1.3.8=py312h5eee18b_0 mkl_random=1.2.4=py312hdb19cb5_0 more-itertools=10.1.0=py312h06a4308_0 mpmath=1.3.0=py312h06a4308_0 mypy_extensions=1.0.0=py312h06a4308_0 mysql=5.7.24=h721c034_2 nbclient=0.8.0=py312h06a4308_0 nbconvert=7.10.0=py312h06a4308_0 nbformat=5.9.2=py312h06a4308_0 ncurses=6.4=h6a678d5_0 nest-asyncio=1.6.0=py312h06a4308_0 nettle=3.7.3=hbbd107a_1 networkx=3.1=py312h06a4308_0 nspr=4.35=h6a678d5_0 nss=3.89.1=h6a678d5_0 numpy=1.26.4=py312hc5e2394_0 numpy-base=1.26.4=py312h0da6c21_0 numpydoc=1.5.0=py312h06a4308_0 openh264=2.1.1=h4ff587b_0 openjpeg=2.4.0=h3ad879b_0 openssl=3.0.13=h7f8727e_1 packaging=23.2=py312h06a4308_0 pandocfilters=1.5.0=pyhd3eb1b0_0 parso=0.8.3=pyhd3eb1b0_0 pathspec=0.10.3=py312h06a4308_0 pcre2=10.42=hebb0a14_0 pexpect=4.8.0=pyhd3eb1b0_3 pickleshare=0.7.5=pyhd3eb1b0_1003 pillow=10.3.0=py312h5eee18b_0 pip=23.3.1=py312h06a4308_0 platformdirs=3.10.0=py312h06a4308_0 pluggy=1.0.0=py312h06a4308_1 ply=3.11=py312h06a4308_1 prompt-toolkit=3.0.43=py312h06a4308_0 prompt_toolkit=3.0.43=hd3eb1b0_0 psutil=5.9.0=py312h5eee18b_0 ptyprocess=0.7.0=pyhd3eb1b0_2 pure_eval=0.2.2=pyhd3eb1b0_0 pybind11-abi=5=hd3eb1b0_0 pycodestyle=2.11.1=py312h06a4308_0 pycparser=2.21=pyhd3eb1b0_0 pydocstyle=6.3.0=py312h06a4308_0 pyflakes=3.2.0=py312h06a4308_0 pygments=2.15.1=py312h06a4308_1 pylint=2.16.2=py312h06a4308_0 pylint-venv=3.0.3=py312h06a4308_0 pyls-spyder=0.4.0=pyhd3eb1b0_0 pyparsing=3.0.9=py312h06a4308_0 pyqt=5.15.10=py312h6a678d5_0 pyqt5-sip=12.13.0=py312h5eee18b_0 pyqtwebengine=5.15.10=py312h6a678d5_0 pysocks=1.7.1=py312h06a4308_0 python=3.12.3=h996f2a0_0 python-dateutil=2.8.2=pyhd3eb1b0_0 python-fastjsonschema=2.16.2=py312h06a4308_0 python-lsp-black=2.0.0=py312h06a4308_0 python-lsp-jsonrpc=1.1.2=pyhd3eb1b0_0 python-lsp-server=1.10.0=py312h06a4308_0 python-slugify=5.0.2=pyhd3eb1b0_0 pytoolconfig=1.2.6=py312h06a4308_0 pytorch=2.3.0=py3.12_cuda11.8_cudnn8.7.0_0 pytorch-cuda=11.8=h7e8668a_5 pytorch-mutex=1.0=cuda pytz=2024.1=py312h06a4308_0 pyxdg=0.27=pyhd3eb1b0_0 pyyaml=6.0.1=py312h5eee18b_0 pyzmq=25.1.2=py312h6a678d5_0 qdarkstyle=3.2.3=pyhd3eb1b0_0 qstylizer=0.2.2=py312h06a4308_0 qt-main=5.15.2=h53bd1ea_10 qt-webengine=5.15.9=h9ab4d14_7 qtawesome=1.2.2=py312h06a4308_0 qtconsole=5.5.1=py312h06a4308_0 qtpy=2.4.1=py312h06a4308_0 readline=8.2=h5eee18b_0 referencing=0.30.2=py312h06a4308_0 requests=2.31.0=py312h06a4308_1 rich=13.3.5=py312h06a4308_1 rope=1.12.0=py312h06a4308_0 rpds-py=0.10.6=py312hb02cf49_0 rtree=1.0.1=py312h06a4308_0 scipy=1.13.0=py312hc5e2394_0 secretstorage=3.3.1=py312h06a4308_1 setuptools=68.2.2=py312h06a4308_0 sip=6.7.12=py312h6a678d5_0 six=1.16.0=pyhd3eb1b0_1 snowballstemmer=2.2.0=pyhd3eb1b0_0 sortedcontainers=2.4.0=pyhd3eb1b0_0 soupsieve=2.5=py312h06a4308_0 sphinx=5.0.2=py312h06a4308_0 sphinxcontrib-applehelp=1.0.2=pyhd3eb1b0_0 sphinxcontrib-devhelp=1.0.2=pyhd3eb1b0_0 sphinxcontrib-htmlhelp=2.0.0=pyhd3eb1b0_0 sphinxcontrib-jsmath=1.0.1=pyhd3eb1b0_0 sphinxcontrib-qthelp=1.0.3=pyhd3eb1b0_0 sphinxcontrib-serializinghtml=1.1.5=pyhd3eb1b0_0 spyder=5.5.1=py312h06a4308_0 spyder-kernels=2.5.0=py312h06a4308_0 sqlite=3.45.3=h5eee18b_0 stack_data=0.2.0=pyhd3eb1b0_0 sympy=1.12=py312h06a4308_0 tbb=2021.8.0=hdb19cb5_0 text-unidecode=1.3=pyhd3eb1b0_0 textdistance=4.2.1=pyhd3eb1b0_0 three-merge=0.1.1=pyhd3eb1b0_0 tinycss2=1.2.1=py312h06a4308_0 tk=8.6.12=h1ccaba5_0 tomli=2.0.1=py312h06a4308_1 tomlkit=0.11.1=py312h06a4308_0 torchaudio=2.3.0=py312_cu118 torchvision=0.18.0=py312_cu118 tornado=6.3.3=py312h5eee18b_0 tqdm=4.66.2=py312he106c6f_0 traitlets=5.7.1=py312h06a4308_0 typing_extensions=4.9.0=py312h06a4308_1 tzdata=2024a=h04d1e81_0 ujson=5.4.0=py312h6a678d5_0 unicodedata2=15.1.0=py312h5eee18b_0 unidecode=1.2.0=pyhd3eb1b0_0 urllib3=2.1.0=py312h06a4308_1 watchdog=2.1.6=py312h06a4308_0 wcwidth=0.2.5=pyhd3eb1b0_0 webencodings=0.5.1=py312h06a4308_2 whatthepatch=1.0.2=py312h06a4308_0 wheel=0.41.2=py312h06a4308_0 wrapt=1.14.1=py312h5eee18b_0 wurlitzer=3.0.2=py312h06a4308_0 xz=5.4.6=h5eee18b_1 yaml=0.2.5=h7b6447c_0 yapf=0.40.2=py312h06a4308_0 zeromq=4.3.5=h6a678d5_0 zipp=3.17.0=py312h06a4308_0 zlib=1.2.13=h5eee18b_1 zstd=1.5.5=hc292b87_1这是什么
最新发布
09-07
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值