mysql 锁表锁行语句分享(MySQL事务处理)
程序员文章站
2023-12-20 10:21:34
复制代码 代码如下: mysql_query("set autocommit=0"); $list_one = $db->fetch_first("select *...
复制代码 代码如下:
mysql_query("set autocommit=0");
$list_one = $db->fetch_first("select * from prizes where id = ".$id." for update");
$db->query("delete from prizes where id =".$list_one['id']);
mysql_query("commit");
start transaction, commit和rollback语法
复制代码 代码如下:
start transaction | begin [work]
commit [work] [and [no] chain] [[no] release]
rollback [work] [and [no] chain] [[no] release]
set autocommit = {0 | 1}
start transaction或begin语句可以开始一项新的事务。commit可以提交当前事务,是变更成为永久变更。rollback可以 回滚当前事务,取消其变更。set autocommit语句可以禁用或启用默认的autocommit模式,用于当前连接。
自选的work关键词被支持,用于commit和release,与chain和release子句。chain和release可以被用于对事务完成进行附加控制。completion_type系统变量的值决定了默认完成的性质。
and chain子句会在当前事务结束时,立刻启动一个新事务,并且新事务与刚结束的事务有相同的隔离等级。release子句在终止了当前事务后,会让服务器断开与当前客户端的连接。包含no关键词可以抑制chain或release完成。如果completion_type系统变量被设置为一定的值,使连锁或释放完成可以默认进行,此时no关键词有用。
默认情况下,mysql采用autocommit模式运行。这意味着,当您执行一个用于更新(修改)表的语句之后,mysql立刻把更新存储到磁盘中。
如果您正在使用一个事务安全型的存储引擎(如innodb, bdb或ndb簇),则您可以使用以下语句禁用autocommit模式:
set autocommit=0;
通过把autocommit变量设置为零,禁用autocommit模式之后,您必须使用commit把变更存储到磁盘中,或着如果您想要忽略从事务开始进行以来做出的变更,使用rollback。
如果您想要对于一个单一系列的语句禁用autocommit模式,则您可以使用start transaction语句:
复制代码 代码如下:
start transaction;
select @a:=sum(salary) from table1 where type=1;
update table2 set summary=@a where type=1;
commit;
使用start transaction,autocommit仍然被禁用,直到您使用commit或rollback结束事务为止。然后autocommit模式恢复到原来的状态。
begin和begin work被作为start transaction的别名受到支持,用于对事务进行初始化。start transaction是标准的sql语法,并且是启动一个ad-hoc事务的推荐方法。begin语句与begin关键词的使用不同。begin关键词可以启动一个begin...end复合语句。后者不会开始一项事务。
您也可以按照如下方法开始一项事务:
start transaction with consistent snapshot;
with consistent snapshot子句用于启动一个一致的读取,用于具有此类功能的存储引擎。目前,该子句只适用于innodb。该子句的效果与发布一个start transaction,后面跟一个来自任何innodb表的select的效果一样。请参见15.2.10.4节,“一致的非锁定读”。
开始一项事务会造成一个隐含的unlock tables被执行。
为了获得最好的结果,事务应只使用由单一事务存储引擎管理的表执行。否则,会出现以下问题:
如果您使用的表来自多个事务安全型存储引擎(例如innodb和bdb),并且事务隔离等级不是serializable,则有可能当一个事务提交时,其它正在进行中的、使用同样的表的事务将只会发生由第一个事务产生的变更。也就是,用混合引擎不能保证事务的原子性,并会造成不一致。(如果混合引擎事务不经常有,则您可以根据需要使用set transaction isolation level把隔离等级设置到serializable。)
如果您在事务中使用非事务安全型表,则对这些表的任何变更被立刻存储,不论autocommit模式的状态如何。
如果您在更新了事务中一个事务表之后,发布一个rollback语句,则会出现一个er_warning_not_complete_rollback警告。对事务安全型表的变更被 回滚,但是对非事务安全型表没有变更。
每个事务被存储在一个组块中的二进制日志中,在commit之上。被回滚的事务不被计入日志。(例外情况:对非事务表的更改不会被 回滚。如果一个被回滚的事务包括对非事务表的更改,则整个事务使用一个在末端的rollback语句计入日志,以确保对这些表的更改进行复制。)
您可以使用set transaction isolation level更改事务的隔离等级。
回滚可以慢速运行。在用户没有明确要求时,也可以进行回滚(例如,当错误发生时)。因此,在明确地和隐含的(rollback sql命令)回滚时,show processlist会在stage列中显示rolling back,用于连接。