`
风雪涟漪
  • 浏览: 508721 次
  • 性别: Icon_minigender_1
  • 来自: 大连->北京
博客专栏
952ab666-b589-3ca9-8be6-3772bb8d36d4
搜索引擎基础(Search...
浏览量:9069
Ae468720-c1b2-3218-bad0-65e2f3d5477e
SEO策略
浏览量:18486
社区版块
存档分类
最新评论

MySQL 架构 - 事务处理

阅读更多

事务处理

在事务处理之前,你不能知道数据库系统有如此多的高级功能。一个事物就是一组SQL查询。这一组被看做是原子的。也就是一个单独的工作单元。如果数据库引擎可以应用整个组的查询,就执行完毕。但是如果其中一条语句出现问题,整个组的语句都不会被执行。也就是要么全部执行,要么全部不执行。

 

这部分所讲到的事物很少是针对MySQL的,如果你已经熟悉了ACID事务处理,可以跳过这一部分。

 

银行的应用是解释为什么需要事务处理的经典案例。假设银行数据有两张表。checking以及savings.从Jane的checking账户转账200到她的saving账户。至少要三步

 

  1. 确定她的checking账户至少有200
  2. 从checking账户扣除200
  3. 把200添加到她的savings账户中。

整个操作封装为了一个事物。因此其中一个操作失败,整个操作都会回滚。

 

开始一个事物的语句是START TRANSACTION以及修改成功用COMMIT或者放弃改变用ROLLBACK。因此这个例子的SQL语句如下

START TRANSACTION;
SELECT balance FROM checking WHERE customer_id = 10233276;
UPDATE checking SET balance = balance - 200.00 WHERE customer_id = 10233276;
UPDATE savings  SET balance = balance + 200.00 WHERE customer_id = 10233276;
COMMIT;

 

但是单独的事物并不能代表全部。如果在数据库服务器在执行到第四行的时候挂掉呢?用户可能就白白损失了200。以及如果有个处理出现在了3,4行之间,而不会去扣除checking帐户的余额。那么银行就白白给了用户200.

 

在系统没有通过ACID的测试之前,仅仅有事物还是不够的。ACID的意思是原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。这些都是一个好的事务处理系统所要遵循的标准。

 

原子性(Atomicity):

一个事物必须做为一个单独不可分割的工作单元来运行。因此整个事物要么全部成功要么全部失败。当事物具有原子性的时候,不能一部分的执行。要么全部执行,要么全部失败。

 

一致性(Consistency):

数据库应该总是从一个一致的状态到另一个。在我们的例子中,一致性要确保程序在3,4行崩溃并不会使checking帐户减少200。因为事物没有提交。数据库没有任何变化。

 

隔离性(Isolation):

当这个事物没有完成的时候,它的结果对于其他的事物是不可见的。这点确保了在运行完第3行,以及在第4行之前。200还是在checking帐户中。当我们讨论隔离性的时候,我们常常用到不可见(invisible)这个词。

 

持久性(Durability):

当事物提交,这个事物的改变就被持久化了。意思就是更改被记录了。数据不会丢失了。持久性是个挺模糊的概念。因为它有很多级别。一些持久性策略比其他的有更强的安全性保证。但是绝对没有100%的持久。我们会在以后的章节讨论在MySQL中持久性的意思。

 

ACID事物保证了银行不会损失钱。这点在业务逻辑上很难或者根本做不到。一个有ACID的数据库服务器已经把各种各样复杂的事情都解决了,使你没有必要自己去确保ACID。

 

随着锁的颗粒度上升,数据库服务器要在安全性上做更多的工作了。数据库的ACID事物也需要更多的CPU,内存,硬盘空间。我们多次说过MySQL存储引擎架构的优势。你可以决定到底是否使用事物。如果不需要可以选择更好的没有事务支持的存储引擎。在没有事物的时候,你可以使用LOCK TABLES来保护数据。决定权在于你。

 

 

隔离级别

隔离要比看上去复杂的多。SQL定义了4种隔离级别。这些规则让更改对事物的内部和外部可见和不可见。低级别的隔离可以高并发低消耗。

(每个存储引擎的隔离级别实现都是不同的,如果你过去经常使用其他数据库产品,存储引擎不一定符合你的需求,你应该看手册决定使用哪个存储引擎。)

 

未提交读(READ UNCOMMITTED)

在这个级别中,事物可以看到未提交事物的结果。这个级别有很多问题会发生,除非你真的真的明白你在做什么以及有足够的理由去做。这级别在实践中很少使用。因为性能相对于其他级别也没什么优势。读取未提交的数据,也叫脏读(dirty read)

 

已提交读(READ COMMITTED)

有许多数据库系统默认的隔离级别都是已提交读(MySQL并不是)。它满足了早期使用的隔离简单定义:一个事物可以看到事物提交后的改变。这种改变在提交之前对于其他事物是不可见的。这级别也经常叫做不可重复读(nonrepeatable read)。意思就是你运行同一语句两次,可以看到不同的数据。

 

可重复读(REPEATABLE READ)

可重复读解决了未提交读的问题。它保证了在同一个事物中,连续任意行的读的数据都是相同的。但这种方式也引起了其他恶心的问题。幻读(phantom reads.)。简单地说就是,当你选择一定范围的行,另一个事物想这个范围新增加了一行。之后有查询相同的范围。你就会发现出现了像幻觉一样的一行。InnoDB和Falcon用多版本并发控制来解决了幻读的问题。

可重复读是MySQL默认的事物隔离级别。InnoDB和Falcon也是遵循这个设置。以后会讲到怎样修改这个设置。其他的引擎也是这样的,但是决定权在于引擎。

 

可序列化(SERIALIZABLE)

最高的隔离级别。解决的幻读的问题。强迫事物是有序的。因此他们不可能冲突。简单的意思就是可序列化把每一行加一个锁。这一级别许多超时和锁的竞争将出现。我们很少看见人们使用这个级别的隔离。你的应用也有可能强迫你把隔离级别设置那么高,而忽视并发性。重视数据的稳定性。

 

 

 

隔离级别 脏读 不可重复读 幻读 读取锁
未提交读             是                   是                  否                     
已提交读
可重复读
可序列化

 

 

死锁(Deadlocks

死锁就是当两个以上的事物相互的等待和请求同一资源,产生了循环依赖就导致死锁。死锁存在事物尝试不同的顺序去锁定资源的时候。在任何时候多事物锁定同一资源都会发生死锁。举个例子。。有两个事物运行在StockPrice的表。

事物一

START TRANSACTION;
UPDATE StockPrice SET close = 45.50 WHERE stock_id = 4 and date = '2002-05-01';
UPDATE StockPrice SET close = 19.80 WHERE stock_id = 3 and date = '2002-05-02';
COMMIT;

 

事物二

START TRANSACTION;
UPDATE StockPrice SET high  = 20.12 WHERE stock_id = 3 and date = '2002-05-02';
UPDATE StockPrice SET high  = 47.20 WHERE stock_id = 4 and date = '2002-05-01';
COMMIT;
 

如果你足够的倒霉,可能会发生如下情况。每个事物都完成第一条语句更新了StockPrice表。给它加了锁。每个事物都试图执行第二行。发现它被加锁了。这两个事物都会等待除自己另外一个事物结束。除非有操作能破坏这个死锁状况。

 

为了解决这个问题,数据库系统实现了许多种死锁的检测和超时处理。在更复杂的系统中,如InnoDB存储引擎。会发现循环依赖并且及时的返回错误。真是非常好的方式,否则死锁会降低语句的执行效率。其他的方式是在锁等待超时之后,放弃操作。这个方式不太好。InnoDB处理死锁的方式是,回滚有最少行级锁的事物。

 

锁的行为和顺序是存储引擎特定的。因此有些存储引擎可能在特定的一系列语句发生死锁,其他的也许不会。死锁有双重特性:一些是不可避免的,因为确实是数据冲突。一些是由于存储引擎工作方式所引起的。

 

事务日志

事物日志的帮助可以让事物更有效率。存储引擎更改存储在内存中的数据拷贝,取代每次修改都要更新硬盘上的表。这种方法非常高效。之后,存储引擎就向事务日志添加一条记录。这个日志存放在硬盘中,因此是持久的。这个操作相对来说能快点。因为附加记录事件使用小范围的连续IO取代了大范围的随机IO。之后,在晚一点,会更新硬盘上的表。所以大部分存储引擎都使用这个技术(write-ahead logging 预写式记录),会两次向硬盘写入更改的信息。

 

在更新日志之后,更改数据之前发生了错误。存储引擎仍然在重启后恢复更改。各个存储引擎的恢复方法各不相同。

 

MySQL中的事物

MySQL提供了三种支持事物的存储引擎: InnoDB, NDB Cluster, Falcon。许多第三方的引擎也可以使用,比较有名的就是solidDB 以及PBXT。在下一部分会详细介绍这些存储引擎。

 

AUTOCOMMIT

MySQL的AUTOCOMMIT是默认的。意思就是无论你是否开始一个事物,在每个语句都会自动执行。当然你可以设置这个AUTOCOMMIT的变量,方法如下


1和ON是一样的。0也就是OFF。当AUTOCOMMIT=0的时候,你必须COMMIT或ROLLBACK,不然的话你就总在一个事物中,语句不会执行。如果表的存储引擎不支持事物,改变AUTOCOMMIT的值,不会有任何的效果。这些存储引擎是MyISAM或者Memory.它们总是自动提交。

 

一些命令,当开始一个事物,在执行之前,MySQL会自动提交事物。这些命令就是DDL。如果ALTER TABLE等,还有一些特殊如LOCK TABLES也会有这样的效果。具体的查看数据库版本的文档。来查看哪些命令是自动提交的。

 

MySQL允许设置隔离级别。命令是SET TRANSACTION ISOLATION LEVEL 。这会影响下一个事物的开始时间。你也可以通过配置文件来设置整个服务器的隔离级别,这个将在以后说。也可以针对当前会话。如

mysql> SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

 

MySQL能识别所有标准的隔离级别,以及InnoDB存储引擎支持这些隔离级别。其他的存储引擎不同程度上支持不同的隔离级别。

 

在事物中混合使用存储引擎

在服务器级别,MySQL不能管理事物。而事物是由存储引擎所实现的。意思就是你不能在一个单独事物中混合使用不同的存储引擎。MySQL AB给服务器添加了一个更高级别的事务管理服务。这样就会在一个事物中,混合和匹配事务表更加安全。在此之前一定要小心。

 

如果在一个事物中混合了事物和非事物表。如果一切正常,这个事物就没有问题,但是如果执行回滚操作,非事物表改变的数据并不会回滚。数据库的一致性遭到了破坏,很难恢复和呈现完整的事物。这就是为什么给表选择存储引擎是如此的重要。

 

如果你在非事物表上做事物操作,MySQL并不会提示或者抛出异常。有的时候,回滚会有一定的提示。“Some nontransactional changed tables couldn’t be rolled back”。但是一般都不会有什么提示。

 

隐式和显式的锁定

InnoDB使用两阶段锁定协议(two-phase locking protocol)。它能任意时间在一个事物之中获得锁。但是只要执行COMMIT或ROLLBACK才会释放锁。它总在同一时刻释放锁。锁机制的描述都是隐式的。InnoDB根据你设置的隔离级别自动处理锁。

 

然而,InnoDB也支持显式加锁。SQL的标准并没有提到:

• SELECT ... LOCK IN SHARE MODE

• SELECT ... FOR UPDATE

 

MySQL也支持LOCK TABLES 和UNLOCK TABLES命令。这个是由服务器实现的。并不是存储引擎。这个可以使用,但它并不不能取代事物。如果你要用事物,请使用支持事物的存储引擎。

 

我们看到很多应用从MyISAM转到InnoDB,但是还在使用LOCK TABLES.这没什么必要,因为行级别的锁定。LOCK TABLE也会引起性能问题。

 

(LOCK TABLES和事物之间的交互是复杂的。可能有些意想不到的异常出现。所以我们建议除非你不使用事物和把AUTOCOMMIT关闭,否则永远不要使用LOCK TABLES。)

  • 大小: 17.8 KB
分享到:
评论

相关推荐

    mysql-connector-java-5.1.44

    6. **事务处理** JDBC支持事务控制,可以通过`Connection`对象的`setAutoCommit`方法关闭自动提交,并使用`commit`和`rollback`方法手动提交或回滚事务。 7. **连接池** 在生产环境中,通常会使用连接池(如C3P0...

    mysql面试题-mysql经典面试题目-数据库的基本概念-SQL语法-事务处理-索引优化-性能调优-mysql-面试题目

    【MySQL面试题】在面试MySQL相关的职位时,面试官可能会问到一系列关于数据库基础、SQL语法、事务处理、索引优化以及性能调优的问题。以下是一些可能的面试重点: 1. **数据库基本概念**: - 数据库是用于存储和...

    MySQL-client-5.6.29-1.linux_glibc2.5.x86_64,MySQL-server-5.6.29-1.linux_glibc

    MySQL-server是MySQL的核心服务组件,负责处理来自客户端的请求,执行SQL语句,并管理数据库的存储和事务处理。5.6.29版本引入了InnoDB存储引擎的改进,如更好的行锁定机制,更高效的全文索引,以及对并行复制的支持...

    mysql-connector-java-8.0.24

    MySQL Connector/J 8.0.24 是MySQL数据库与Java应用程序之间的重要桥梁,它是一个用于连接Java...最后,了解并遵循MySQL的最佳实践,如合理设计数据库架构、索引管理和事务处理,有助于提升整个系统的稳定性和效率。

    mysql-cluster-8.0.20-winx64.zip

    MySQL Cluster是一种高可用性、高性能的数据库解决方案,它在MySQL服务器的基础上增加了分布式数据存储和实时事务处理的能力。在“mysql-cluster-8.0.20-winx64.zip”这个压缩包中,我们找到了MySQL Cluster的...

    mysql57-community-release-el7-11.noarch.rpm

    2. **InnoDB增强**:InnoDB存储引擎在5.7版本中得到了显著强化,包括支持更大的索引键、更高效的事务处理以及更好的行格式(例如DYNAMIC和COMPRESSED)。 3. **JSON支持**:MySQL 5.7引入了对JSON数据类型的原生...

    mysql-community-server-8.4.0-1.el9.x86-64

    2. **社区服务器**:MySQL Community Server是开源的,由MySQL社区维护和开发,提供了完整的数据库服务功能,包括SQL支持、事务处理、复制、安全性和备份等。 3. **x86_64架构**:这个版本是为64位系统设计的,意味...

    mysql-connector-java-5.1.30-bin.rar

    这个版本支持MySQL 5.1.x系列,提供了一整套功能,包括连接管理、事务处理、预编译的SQL语句、结果集处理等。"bin"后缀表明这个jar文件包含了可执行的二进制代码,可以直接在Java环境中运行。 在Android开发中,...

    MySQL驱动 mysql-connector-net-6.4.4

    5. **事务处理**:MySQL Connector/NET支持事务处理,开发者可以通过`MySqlConnection`的`BeginTransaction`、`Commit`和`Rollback`方法来控制事务的生命周期,确保数据的一致性和完整性。 6. **参数化查询**:为...

    MySQL-5.5.28-winx64安装包以及说明文档

    - **存储引擎**:MySQL支持多种存储引擎,如InnoDB(支持事务处理和外键)、MyISAM(快速读取,不支持事务)和Memory(数据存储在内存中)。选择合适的存储引擎对性能有很大影响。 - **索引**:创建索引可以加速...

    最新mysql-connector-java-5.1.46(领附MySQL向Oracle迁移教程)

    这个驱动程序符合JDBC(Java Database Connectivity)标准,使得Java开发者能够方便地执行SQL语句、管理数据库事务以及处理结果集。 在Java应用中,使用`mysql-connector-java`驱动主要是通过以下步骤: 1. **引入...

    mysql-5.7.32-linux-glibc-2.28-aarch64.tar.gz

    - **InnoDB存储引擎的改进**:支持更高的并发性,更快的全文搜索,以及更好的事务处理性能。 - **Performance Schema**:提供详细的性能监控,帮助管理员分析和优化数据库性能。 - **JSON支持**:引入了对JSON数据...

    mysql-connector-java-8.0.21.rar

    在MyBatis中,通过配置数据源和事务管理器,可以指定使用MySQL Connector/J作为数据库连接驱动。例如,在MyBatis的配置文件中: ```xml <property name="driver" value="com.mysql.cj.jdbc.Driver"/> ...

    mysql-essential-5.0.45

    1. **事务处理支持**: MySQL 5.0引入了InnoDB存储引擎,提供了ACID(原子性、一致性、隔离性、持久性)事务支持,这对于需要高度数据一致性的应用至关重要。 2. **SQL标准兼容性**: MySQL 5.0增强了对SQL92和SQL99...

    mysql-connector-java-5.1.40

    4. **事务处理**:支持ACID(原子性、一致性、隔离性和持久性)事务特性,可进行提交、回滚等操作。 5. **数据库元数据**:获取关于数据库架构、表、列等信息,用于动态构建SQL语句或数据库维护。 6. **类型映射**:...

    MySQL-5.6.17-liunx-32bit

    MySQL是世界上最受欢迎的关系型数据库管理系统(RDBMS)之一,尤其在Web应用程序中广泛使用。本文将详述关于“MySQL-...安装完成后,你可以开始利用MySQL的强大功能,比如创建数据库、表,进行数据查询和事务处理等。

    mysql源码(mysql-8.2.0.zip)

    MySQL的源码分析可以帮助我们深入了解其内部工作机制,包括查询优化、事务处理、存储引擎等核心功能。`mysql-8.2.0.zip`是MySQL的一个特定版本,以下是关于这个版本的一些关键知识点: 1. **版本更新**:MySQL ...

    Windows10上安装的mysql-8.0.36-winx64.zip版本压缩包

    MySQL 8.0 提供了对于大型查询和事务处理的更好性能支持。引入了自适应哈希索引(AHI),这是除了普通的B树索引之外的另一种索引类型,用于内存内嵌表的小键值高速哈希索引,有助于提高查询效率。新的数据字典架构...

    MySQL 5.6 for Windows 官方(mysql-5.6.34-winx64.zip)

    - **ACID合规性**:进一步提升了事务处理能力,保证了数据的一致性和完整性。 - **复制改进**:增强了复制功能,支持半同步复制,确保数据的一致性,并提供了更好的故障恢复机制。 - **查询优化器改进**:采用了...

Global site tag (gtag.js) - Google Analytics