概念
<span style="color: rgb(51, 51, 51); font-family: arial, 宋体, sans-serif; font-size: 14px; text-indent: 28px;">指作为单个逻辑工作单元执行的一系列</span><a target="_blank" href="http://baike.baidu.com/subview/60435/8049868.htm" data-lemmaid="33052" style="color: rgb(19, 110, 194); text-decoration: none; font-family: arial, 宋体, sans-serif; font-size: 14px; text-indent: 28px;">操作</a><span style="color: rgb(51, 51, 51); font-family: arial, 宋体, sans-serif; font-size: 14px; text-indent: 28px;">,要么完全地执行,要么完全地不执行</span>
作用
<span style="color: rgb(153, 153, 153); font-family: "Microsoft Yahei"; font-size: 16px;">1、为数据库操作提供了一个从失败中恢复到正常状态的方法,同时提供了数据库即使在异常状态下仍能保持一致性的方法。</span>
<span style="color: rgb(153, 153, 153); font-family: "Microsoft Yahei"; font-size: 16px;">2、当多个应用程序在并发访问数据库时,可以在这些应用程序之间提供一个隔离方法,以防止彼此的操作互相干扰。</span>
特性
原子性
<span style="color: rgb(153, 153, 153); font-family: "Microsoft Yahei"; font-size: 16px;">:事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。</span>
一致性
<font color="#999999" face="Microsoft Yahei"><span style="font-size: 16px;">事务在完成时必须保持数据的一致性</span></font>
隔离性
<span style="color: rgb(153, 153, 153); font-family: "Microsoft Yahei"; font-size: 16px;">多个事务并发执行时,一个事务的执行不应影响其他事务的执行。</span>
持久性
<span style="color: rgb(153, 153, 153); font-family: "Microsoft Yahei"; font-size: 16px;">一个事务一旦提交,他对数据库的修改应该永久保存在数据库中。</span>
隔离级别
<span style="color: rgb(102, 102, 102); font-family: 宋体, Arial; font-size: 15px;">默认的行为(不带session和global)是为下一个(未开始)事务设置隔离级别。如果你使用GLOBAL关键字,语句在全局对从那点开始创建的所有新连接(除了不存在的连接)设置默认事务级别。你需要SUPER权限来做这个。使用SESSION 关键字为将来在当前连接上执行的事务设置默认事务级别。 任何客户端都能自由改变会话隔离级别(甚至在事务的中间),或者为下一个事务设置隔离级别。</span>
<pre courier="" new"="" !important;font-size:12px="" !important;white-space:pre-wrap;-ms-word-wrap:break-word;"="" style="word-wrap: break-word; margin-top: 0px; margin-bottom: 0px; padding: 0px; color: rgb(0, 0, 0); font-size: 12px;"><span courier="" new"="" !important;font-size:12px="" !important;"="" style="word-wrap: break-word; margin: 0px; padding: 0px; color: rgb(0, 0, 255); line-height: 1.5 !important;">SELECT</span> <span courier="" new"="" !important;font-size:12px="" !important;font-weight:bold;"="" style="word-wrap: break-word; margin: 0px; padding: 0px; color: rgb(0, 128, 0); line-height: 1.5 !important;">@@global</span><span courier="" new"="" !important;font-size:12px="" !important;"="" style="word-wrap: break-word; margin: 0px; padding: 0px; line-height: 1.5 !important;">.tx_isolation; </span></pre><pre courier="" new"="" !important;font-size:12px="" !important;white-space:pre-wrap;-ms-word-wrap:break-word;"="" style="word-wrap: break-word; margin-top: 0px; margin-bottom: 0px; padding: 0px; color: rgb(0, 0, 0); font-size: 12px;"><span courier="" new"="" !important;font-size:12px="" !important;"="" style="word-wrap: break-word; margin: 0px; padding: 0px; line-height: 1.5 !important;"></span><span courier="" new"="" !important;font-size:12px="" !important;"="" style="word-wrap: break-word; margin: 0px; padding: 0px; color: rgb(0, 0, 255); line-height: 1.5 !important;">SELECT</span> <span courier="" new"="" !important;font-size:12px="" !important;font-weight:bold;"="" style="word-wrap: break-word; margin: 0px; padding: 0px; color: rgb(0, 128, 0); line-height: 1.5 !important;">@@session</span><span courier="" new"="" !important;font-size:12px="" !important;"="" style="word-wrap: break-word; margin: 0px; padding: 0px; line-height: 1.5 !important;">.tx_isolation; </span></pre>
可序列化
<span style="color: rgb(102, 102, 102); font-family: Helvetica, arial, "Hiragino Sans GB", "Microsoft Yahei", Verdana, Arial, sans-serif; font-size: 15px; background-color: rgb(253, 253, 253);">此级别下运行的事务是完全隔离的,不会受到其他事务的干扰(因此不会出现任何“读现象”)。</span>
<span style="color: rgb(85, 85, 85); font-size: 15px; font-family: "Times New Roman";">Serializable </span><span style="color: rgb(85, 85, 85); font-size: 15px; font-family: 宋体;">的时候,虽然可以避免所有并发访问的问题,但是 </span><span style="color: rgb(85, 85, 85); font-size: 15px; font-family: "Times New Roman";">Serializable </span><span style="color: rgb(85, 85, 85); font-size: 15px; font-family: 宋体;">采用的是单线程来解决并发访问的问题,也就是说在某一段时间内,只能有一个用户对数据库进行操作,导致其它用户阻塞。导致数据库的访问性能很差。</span>
<p style="box-sizing: border-box; margin: 1.5em 0px; color: rgb(51, 51, 51); font-family: "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "WenQuanYi Micro Hei", "Microsoft Yahei", sans-serif; font-size: 14px;">这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。SERIALIZABLE 事务隔离级别最严厉,在进行查询时就会对表或行加上共享锁,其他事务对该表将只能进行读操作,而不能进行写操作。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。</p><div><br></div>
子主题
可重复读
<span style="color: rgb(51, 51, 51); font-family: "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "WenQuanYi Micro Hei", "Microsoft Yahei", sans-serif; font-size: 14px;">这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。</span>
<span style="color: rgb(51, 51, 51); font-family: "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "WenQuanYi Micro Hei", "Microsoft Yahei", sans-serif; font-size: 14px;">幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。</span>
子主题
提交读
<span style="color: rgb(51, 51, 51); font-family: "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "WenQuanYi Micro Hei", "Microsoft Yahei", sans-serif; font-size: 14px;">这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。</span><br style="box-sizing: border-box; color: rgb(51, 51, 51); font-family: "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "WenQuanYi Micro Hei", "Microsoft Yahei", sans-serif; font-size: 14px;"><span style="color: rgb(51, 51, 51); font-family: "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "WenQuanYi Micro Hei", "Microsoft Yahei", sans-serif; font-size: 14px;">它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。</span><br style="box-sizing: border-box; color: rgb(51, 51, 51); font-family: "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "WenQuanYi Micro Hei", "Microsoft Yahei", sans-serif; font-size: 14px;"><span style="color: rgb(51, 51, 51); font-family: "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "WenQuanYi Micro Hei", "Microsoft Yahei", sans-serif; font-size: 14px;">这种隔离级别 也支持所谓的不可重复读(NonrepeatableRead),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一 select 可能返回不同结果。</span>
<span style="color: rgb(85, 85, 85); font-family: "Microsoft Yahei"; font-size: 15px;">在一个事务修改数据过程中,如果事务还没提交,其他事务不能读该数据。</span>
子主题
未提交读
一个事务可以读到另一个事务未提交的数据
事务在读数据的时候并未对数据库加锁
<span style="color: rgb(51, 51, 51); font-family: "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "WenQuanYi Micro Hei", "Microsoft Yahei", sans-serif; font-size: 14px;">在该隔离级别,所有事务都可以看到其他未提交(commit)事务的执行结果。</span><br style="box-sizing: border-box; color: rgb(51, 51, 51); font-family: "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "WenQuanYi Micro Hei", "Microsoft Yahei", sans-serif; font-size: 14px;"><span style="color: rgb(51, 51, 51); font-family: "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "WenQuanYi Micro Hei", "Microsoft Yahei", sans-serif; font-size: 14px;">本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。</span><br style="box-sizing: border-box; color: rgb(51, 51, 51); font-family: "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "WenQuanYi Micro Hei", "Microsoft Yahei", sans-serif; font-size: 14px;"><span style="color: rgb(51, 51, 51); font-family: "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "WenQuanYi Micro Hei", "Microsoft Yahei", sans-serif; font-size: 14px;">读取未提交的数据,也被称之为脏读(Dirty Read)。</span>
读现象
概念:<span style="color: rgb(102, 102, 102); font-family: Helvetica, arial, "Hiragino Sans GB", "Microsoft Yahei", Verdana, Arial, sans-serif; font-size: 15px; background-color: rgb(253, 253, 253);">“读现象”是多个事务并发执行时,在读取数据方面可能碰到的状况。</span>
类型
幻读
<span style="color: rgb(0, 0, 0); font-family: Arial; font-size: 14px;">eg:财务部将小明这个月薪水6000元打入小明账户,小明看到非常高兴,这时候财务部发现打错了,应该是2000元,回滚事务,给小明工资改成2000,小明空欢喜一场。</span>
不可重复读
<p style="box-sizing: border-box; margin: 1em 0px; color: rgb(102, 102, 102); font-family: Helvetica, arial, "Hiragino Sans GB", "Microsoft Yahei", Verdana, Arial, sans-serif; font-size: 15px; background-color: rgb(253, 253, 253);">还是将一条 SELECT 语句执行两次,某个特定的条目在这两次查询中返回的值不一样,就叫“不可重复读”。</p><pre style="box-sizing: border-box; margin-top: 1.6em; margin-bottom: 1.6em; border: 1px solid rgb(227, 237, 243); width: 910px; padding: 10px; font-family: Inconsolata, monospace, sans-serif; font-size: 0.9em; overflow: auto; background: rgb(247, 250, 251); border-radius: 3px; color: rgb(102, 102, 102);"><code style="box-sizing: border-box; padding: 0px; font-family: Inconsolata, monospace, sans-serif; font-size: inherit; white-space: pre-wrap; border: none; background: transparent; color: rgb(51, 51, 51); border-radius: 2px;">SELECT id, name FROM test; => (1,"n1"), (2, "n2), (5, "n5")
SELECT id, name FROM test; => (1, "n1"), (2, "David"), (5, "n5")
注意,返回的仍然是主键为 1,2,5 的数据,但 id=2 的那行数据的 name 变了</code></pre><p style="box-sizing: border-box; margin: 1em 0px; color: rgb(102, 102, 102); font-family: Helvetica, arial, "Hiragino Sans GB", "Microsoft Yahei", Verdana, Arial, sans-serif; font-size: 15px; background-color: rgb(253, 253, 253);">这种情况的原因是:在第二次 SELECT 前,其它事务对此条目进行了 UPDATE,并进行了提交。</p><div><br></div>
脏读
<p style="box-sizing: border-box; margin: 1em 0px; color: rgb(102, 102, 102); font-family: Helvetica, arial, "Hiragino Sans GB", "Microsoft Yahei", Verdana, Arial, sans-serif; font-size: 15px; background-color: rgb(253, 253, 253);">脏读发生的前提是一个事务能读到其他事务中未提交的操作。<br style="box-sizing: border-box;">如果在读取到这样的数据后,那个事务进行了回滚,我们就相当于读到了数据库中不再存在的数据(也就是“脏数据”)。</p><p style="box-sizing: border-box; margin: 1em 0px; color: rgb(102, 102, 102); font-family: Helvetica, arial, "Hiragino Sans GB", "Microsoft Yahei", Verdana, Arial, sans-serif; font-size: 15px; background-color: rgb(253, 253, 253);">这三种读现象是并列、互不相关的,例如在某个隔离等级中出现了“不可重复读”,并不意味着就一定也能出现“幻读”。</p><div><br></div>
锁机制
概念:<span style="color: rgb(85, 85, 85); font-family: "Microsoft Yahei"; font-size: 15px;">当并发事务同时访问一个资源时,有可能导致数据不一致,因此需要一种机制来将数据访问顺序化,以保证数据库数据的一致性。锁就是其中的一种机制。</span>