日期:2014-05-16 浏览次数:20854 次
Mysql使用了一个平面事务模型:嵌套的事务是不允许的,在第一个里面使用start transaction或者begin之后,第二个事务开始的时候,
自动的提交第一个事务。同样,许多其他的Mysql命令运行的时候都会隐藏的执行一个commit命令,下面是一个列表:
DROP DATABASE/DROP TABLE CREATE INDEX/DROP INDEX ALTER TABLE/RENAME TABLE LOCK TABLES/UNLOCK TABLES SET AUTOCOMMIT=1
?Mysql4.0.14和4.1.1,支持保存点,可以在事务中关键的地方做标记,需要的话可以部分撤销。
Mysql提供了两个变量控制事务行为---AUTOCOMMIT 和 TRANSACTION ISOLATION LEVEL
默认情况下是自动提交的,SET AUTOCOMMIT=0可以关掉自动提交,如果退出没有提交,则自动回滚。
通过SELECT @@AUTOCOMMIT;
取得当前的自动提交模式。
mysql> select @@AUTOCOMMIT; +--------------+ | @@AUTOCOMMIT | +--------------+ | 1 | +--------------+ 1 row in set (0.00 sec)
?事务孤立性
Mysql提供了四种孤立级别:
序列化(SERIALIZABLE)
可重复读(REPEATABLE READ)
提交的读(READ COMMITTED)
未提交的读(READ UNCOMMITTED)
序列化:
提供最大程度的隔离,如果每个事务都以这种孤立级运行就会影响Mysql的性能,因为需要大量的资源来使大量事务在任一时刻不被看到。
可重复读:
看起来和序列化的孤立级别很相似。
有一个很重要的不同点:虽然一个事务不能看到其他正在执行的当前事务做出的变化,但是它可以看到新的纪录(其他事务添加到数据库的)。
提交的读:
安全性比可重复读要差。
不仅处于这一级的事务可以看到其他事务添加的新纪录,而且其他事务对现存纪录做出的修改一旦被提交,也可以看到。
也就是说,这意味着在事务处理期间,如果其他事务修改了相应的表,那么同一个事务的多个select语句可能返回不同的结果。
未提交的读:
提供了事务之间最小程度的隔离。除了容易产生虚幻的读操作和不能重复的读操作外,处于这个孤立级的事务可以读到其他事务还没有提交的
数据。如果这个事务使用其他事务未提交的变化作为计算的基础,然后那些未提交的变化被他们的父事务撤销,则导致了大量的数据变化。
可以通过
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
?修改孤立级别。
默认是可重复读的
取得当前的孤立级别:
mysql> select @@tx_isolation; +-----------------+ | @@tx_isolation | +-----------------+ | REPEATABLE-READ | +-----------------+ 1 row in set (0.00 sec)
?默认情况下,这个变量的值是基于每个会话设置的,但是可以通过添加global关键字对所有的会话进行全局设置。
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
需要super优先权执行这个操作。
具有非事物表的伪事务
InnoDB和BDB表支持事物的概念,MyISAM表类型不支持这些锁定机制。所以要明确设置表锁定,以避免同时存在的事物互相侵犯空间。
Mysql提供了以下实现表锁定的句法:
LOCK TABLES table-name lock-type,....
解锁命令:
UNLOCK TABLES;
不用指定解锁的表名。
有两种类型的表锁定:读锁定和写锁定。
读锁定:
表的读锁定是指设置锁定的线程可以从表中读数据,其他线程也可以。不过每个线程都不能修改锁定的表,只要锁定处于活动状态就不能添加、
更新或者删除纪录。
READ锁定的一个变体是READ LOCAL锁定,它和常规的READ锁定是不同的,因为其他线程可以执行INSERT语句,它和初始化锁定的线程拥有的
会话不冲突。它是为了使用mysqldump工具对一个表同时进行多个INSERT操作而创建的。
写锁定:
表的写锁定是指设置锁定的线程可以修改表中的数据,但是其他线程在锁定期间既不能从表中读数据也不能写数据。
锁定的优先权:
在同时涉及到WRITE和READ锁定的情况下,MYSQL对于写锁定分配较高的优先级来保证对于表的修改可以尽快地保存到磁盘上。这就降低了
磁盘崩溃或者系统失败导致更新丢失的危险。
表锁定重要的缺点之一:
如果一个线程不释放它的锁定,其他试图访问这个已锁定表的尝试都会超时等待,导致了整体性能很大程度的降低。
?