缺省的,MySQL 运行在 autocommit
模式。这就意味着,当你执行完一个更新时,MySQL 将立刻将更新存储到磁盘上。 如果你使用事务安全表 (例如 Innodb
、BDB
),通过下面的命令,你可以设置 MyS开发云主机域名QL 为非 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
): 你可以使用 SET TRANSACTION ISOLATION LEVEL ...
改变事务的隔离级。查看章节 6.7.3 SET TRANSACTION
句法。 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
锁被释放。如果这在你的应用程序中会引起一个严重的问题,你应该考虑将你的某些表转换为事务安全表。 你可以使用 KILL
安全地杀死一个正在表锁定的线程。查看章节 4.5.5 KILL
句法。 注意,你不应该 锁定你正在对其使用 INSERT DELAYED
的表。这是因为,在这种情况下,INSERT
是通过单独的线程完成的。 通常,你不需要锁定任何表,因为所有单 UPDATE
语句都是原子的;其它的线程无法干扰当前执行的 SQL 语句。当你无论如何希望锁定表时,这里有一些情况: 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; 通过使用递增更新 (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
不是事务安全的,在尝试锁定一个表之前,将自动地提交所有的活动事务。 SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE } 设置全局的、整个会话或下一个事务的事务隔离级。 缺省行为是设置下一个(未启动的)事务的隔离级。如果你使用 GLOBAL
关键词,语句为所有在那个点上建立的新连接设置默认的全局事务隔离级。为了这样做,你需要有 SUPER
权限。使用 SESSION
关键词为当前连接所有将来执行的事务设置默认的事务隔离级。 你可以使用 --transaction-isolation=...
为 mysqld
设置默认的全局隔离级。查看章节 4.1.1 mysqld
命令行选项。
Innodb存储引擎实现了两种行级锁: l 共享锁 l 排他锁 这两种锁之间的兼容关系如下图所示 共享锁 排他锁 共享锁 兼容 不兼容 排他锁 不兼容 不兼容 关于行级锁比较容易理解。下面介绍一下表级意向锁。 Innodb存储引擎支持多粒度的锁定,换句话说,允…
免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。