mysql事务(mysql TRANSACTION)(一)

来源:互联网 发布:淘宝人群标签是什么 编辑:程序博客网 时间:2024/05/22 12:27

最近碰到Mysql事务的问题。

先查查学习一下。

什么是事务?
我没找到最标准的定义文档,但感觉维基百科上最标准下面是维基百科上的 定义:

一个数据库事务通常包含了一个序列的对数据库的读/写操作。它的存在包含有以下两个目的:

  1. 为数据库操作序列提供了一个从失败中恢复到正常状态的方法,同时提供了数据库即使在异常状态下仍能保持一致性的方法。
  2. 当多个应用程序在并发访问数据库时,可以在这些应用程序之间提供一个隔离方法,以防止彼此的操作互相干扰。

当事务被提交给了DBMS(数据库管理系统),则DBMS(数据库管理系统)需要确保该事务中的所有操作都成功完成且其结果被永久保存在数据库中,如果事务中有的操作没有成功完成,则事务中的所有操作都需要被回滚,回到事务执行前的状态;同时,该事务对数据库或者其他事务的执行无影响,所有的事务都好像在独立的运行。

首先,事务不仅仅针对于修改操作,读也算事务的一部分。
然后,我们具体看看mysql的事务

1.自动提交 (autocommit)

By default, MySQL runs with autocommit mode enabled. This means that
as soon as you execute a statement that updates (modifies) a table,
MySQL stores the update on disk to make it permanent. The change
cannot be rolled back

默认情况下,mysql开启自动提交,就是一旦执行语句就会立即生效。否则需要显示的调用commit。

打开关闭开关

SET autocommit = {0 | 1}

2. Locking Reads

就是在mysql读取数据的时候可以加锁,如下:
SELECT * FROM parent WHERE NAME = 'Jones' LOCK IN SHARE MODE;

读锁有两种

1. SELECT … LOCK IN SHARE MODE

Sets a shared mode lock on any rows that are read. Other sessions can
read the rows, but cannot modify them until your transaction commits.
If any of these rows were changed by another transaction that has not
yet committed, your query waits until that transaction ends and then
uses the latest values.

读锁,其他的会话只可以读不能修改,如果其他事务修改了但还没有提交,读会等待提交获取最新值。

e.g.
SELECT * FROM parent WHERE NAME = 'Jones' LOCK IN SHARE MODE;

2. SELECT … FOR UPDATE

For index records the search encounters, locks the rows and any
associated index entries, the same as if you issued an UPDATE
statement for those rows. Other transactions are blocked from updating
those rows, from doing SELECT … LOCK IN SHARE MODE, or from reading
the data in certain transaction isolation levels. Consistent reads
ignore any locks set on the records that exist in the read view. (Old
versions of a record cannot be locked; they are reconstructed by
applying undo logs on an in-memory copy of the record.)

这里是说查询的时候,会阻塞其他更新的事务,和SELECT … LOCK IN SHARE MODE,以及其他特定事务级别的读数据。

e.g.
SELECT * FROM parent WHERE NAME = 'Jones' FOR UPDATE

官方的解释好像,很混乱,这里网友解释

所以两者的区别是 for update用的排它锁查询,所以会阻塞其它带锁的查询(包括lock in share mode 和 for update)

注: SELECT FOR UPDATE 只有非自动提交,或者在事务里面才生效, 要不然是不会锁的

然后文档上还有两种用法的示例:
1.lock in share mode
对于person一对多dogs表,想为人增加一条狗,但增加狗的时候确保人还在可以用

beginselect * from person where name=“小王” lock in share mode;insert into dogs (id, persion_id) values(1,1);commit;
  1. for update
    当碰到counter计数的时候,几个进程同时改
SELECT counter_field FROM child_codes FOR UPDATE;UPDATE child_codes SET counter_field = counter_field + 1;

因为for update用的是排他锁,所以会阻塞其它带锁的查询来查询这条数据,所以下一个带有(for update 或者 lock in share mode)会阻塞。

mysql 锁的隔离级别
http://www.cnblogs.com/snsdzjlz320/p/5761387.html