MySQL 事务与锁定命令
6.7.1. BEGIN/COMMIT/ROLLBACK句法
缺省的,MySQL 运行在autocommit模式。这就意味着,当你执行完一个更新时,MySQL 将立刻将更新存储到磁盘上。
如果你使用事务安全表 (例如InnoDB、BDB),通过下面的命令,你可以设置 MySQL 为非autocommit模式:
SET AUTOCOMMIT=0
在此之后,你必须使用COMMIT来存储你的更改到磁盘上,或者使用ROLLBACK,如果你希望忽略从你的事务开始所做的更改。
如果你希望为一系列语句从AUTOCOMMIT模式转换,你可以使用START TRANSACTION或BEGIN或BEGIN 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 TRANSACTION或SET 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
|
|
|
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 中,你对该表需要有SELECT、insert、DELETE和UPDATE权限。
使用LOCK TABLES的主要原因是,仿效事务处理或在更新表时得到更快的速度。此后会有更详细的描述。
如果一个线程在一个表上得到一个READ锁,该线程 (和所有其它线程) 只能从表中读取。如果一个线程在一个表上得到一个WRITE锁,那么只有拥有这个锁的线程可以从表中读取和写表。其它的线程被阻塞。
READ LOCAL和READ之间的不同就在于,当锁被加载时,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工作如下:
- 以内部定义的次序排序所有被锁定的表 (从用户立场说,该次序是不明确的)。
- 如果一个表被以一个读锁和一个写锁锁定,将写锁放在读锁之前。
- 一次只锁定一个表,只到线程得到所有的锁定。
这个方案是为了确保,表锁定死锁释放。对于这个模式你仍然有些其它事情需要知道:
如果你对一个表使用一个LOW_PRIORITY WRITE锁定,这就意味着,MySQL 将等待这个锁,直到没有线程请求一个READ锁。当线程得到了WRITE锁,并等待获得锁定表列表中的下一个表的锁定时,其它所有的线程将等待WRITE锁被释放。如果这在你的应用程序中会引起一个严重的问题,你应该考虑将你的某些表转换为事务安全表。
注意,你不应该锁定你正在对其使用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,将可能发生在SELECT和UPDATE语句执行期间有另外一个线程可能在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 辅助功能函数。
你可以使用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关键词为当前连接所有将来执行的事务设置默认的事务隔离级。
分享到:
相关推荐
6.7 MySQL 事务与锁定命令 6.7.1 BEGIN/COMMIT/ROLLBACK 句法 6.7.2 LOCK TABLES/UNLOCK TABLES 句法 6.7.3 SET TRANSACTION 句法 6.8 MySQL 全文搜索 6.8.1 全文的限制 6.8.2 微调 MySQL 全文搜索 ...
### MySQL事务控制与分布式事务详解 #### 表锁机制概览 MySQL的表锁机制针对不同存储引擎提供了差异化的锁定策略。MyISAM和Memory存储引擎支持表级锁定,这意呈着一次只能有一个进程访问特定表进行写入操作,而...
### MySQL事务处理用法与实例详解 #### 一、事务的概念及重要性 在数据库管理中,事务(Transaction)是指一系列作为一个整体的操作序列。这些操作要么全部成功,要么全部失败,不能只执行其中的一部分。事务处理...
### MySQL事务的隔离性 #### 一、事务与MySQL架构 **事务**是数据库管理系统执行过程中的一系列逻辑操作,这些操作作为一个完整的单元被执行。如果事务内的所有操作都成功完成,则整个事务成功;如果其中一个操作...
在MySQL数据库管理中,锁定与解锁是至关重要的概念,它们主要用于多用户环境下的并发控制,以确保数据的一致性和完整性。本课程的目标是使学习者理解锁定和解锁的基本原理,并能够熟练设置这两种操作。 锁定机制在...
### MySQL与事务处理详解 #### 一、引言 MySQL作为一种广泛使用的开源关系型数据库管理系统,在数据管理和存储方面发挥着重要作用。尽管MySQL5.x已经发布了很长时间,但仍有一些人错误地认为MySQL不支持事务处理...
例如,对于InnoDB引擎,它支持事务、行级锁定和外键,而MyISAM则不支持这些特性。 #### 四、查看引擎插件 MySQL还允许用户安装额外的插件来扩展其功能。可以使用以下命令来查看当前系统中已安装的插件: ```sql ...
在MySQL中,`UPDATE`语句的锁定范围与数据库的隔离级别、存储引擎以及所使用的索引类型等因素密切相关。以下将详细阐述这些知识点。 1、**背景** 在数据库操作中,`UPDATE`语句用于修改已存在的数据。了解它会锁定...
MySQL 事务表与非事务表是数据库管理中的两种基本类型,它们主要的区别在于对数据一致性和安全性提供的保障程度。在MySQL中,这两种类型的表在处理数据操作时有不同的机制。 首先,事务表,如InnoDB存储引擎提供的...
【MySQL事务剖析1】 在数据库管理系统中,事务是确保数据一致性的重要机制。事务是一组数据库操作,这些操作被视为一个逻辑工作单元,要么全部执行,要么全部不执行,以保证数据的完整性和一致性。事务的引入解决了...
根据提供的文件信息,本文将详细解释MySQL事务处理的相关知识点,并结合具体的示例代码进行说明。 ### MySQL事务处理基础 在数据库操作中,事务处理是非常重要的一个环节,它能够确保数据的一致性和完整性。MySQL...
MySQL中的事务处理是数据库...此外,数据库管理系统还会自动处理某些并发问题,如脏读、连锁退出和表定义的并发修改,但其他问题(如丢失修改、读的不可重复性)通常需要在应用程序中通过事务管理和锁定策略来解决。
- MySQL 通过 `ROLLBACK` 事务来撤销已执行的操作,Redis 使用 `DISCARD` 命令取消事务,但它不会回滚已执行的命令,因为Redis的事务在 `EXEC` 之前不执行任何命令。 3. **提交事务**: - MySQL 使用 `COMMIT` ...
`命令来查看当前的事务隔离级别,也可以在`my.cnf`配置文件中通过`transaction_isolation`参数进行设置。 在可重复读隔离级别下,事务2可以看到事务1开始时的数据状态,即使事务1已经提交了修改。这是因为InnoDB...
MySQL数据库的事务隔离级别是数据库管理系统中用于控制事务处理中并发操作的重要机制。在多用户同时访问数据库的情况下,事务隔离级别能够确保数据的一致性和完整性,避免并发操作带来的各种问题,如脏读、不可重复...
### MySQL事务及锁原理详解 #### 一、事务的基本概念 事务(Transaction)是数据库操作的基本单位,一组逻辑上完整的工作单元。在事务中,一系列的操作要么全部完成,要么都不进行,确保了数据的一致性和可靠性。...
例如,InnoDB是MySQL最常用的事务型存储引擎,它支持行级锁定,可以有效提高并发性能。 事务的ACID特性: - **原子性(Atomicity)**:事务中的所有操作要么全部成功,要么全部失败,不会留下部分完成的操作。 - **...
在MySQL中,可以通过以下命令设置事务的隔离级别: ```sql SET SESSION TRANSACTION ISOLATION LEVEL ; ``` 其中 `<level>` 可以是 `READ UNCOMMITTED`、`READ COMMITTED`、`REPEATABLE READ` 或 `SERIALIZABLE`。...
在PHP中,可以使用`mysql_query()`函数执行这些SQL命令来处理MySQL事务。例如: ```php mysql_query("BEGIN"); // 执行一系列SQL操作 if (所有操作成功) { mysql_query("COMMIT"); } else { mysql_query(...
- InnoDB是目前的默认引擎,提供了事务处理、行级锁定和ACID兼容性,适合需要事务安全的应用。 - BDB(Berkeley DB)也是一种事务型引擎,提供事务特性如COMMIT和ROLLBACK。 3. **ACID 属性**: - **原子性**:...