更新丢失
使用可更新的游标时,防止更新丢失很重要。更新丢失是这样一种情况:两个或多个事务更新同一行,但这些事务彼此之间都不知道其它事务进行的修改,因此第二个更改覆盖了第一个修改。下面示例说明了此问题:
1. 某个应用程序在以下针对示例数据库的查询中打开一个游标。
2. SELECT ID, Quantity
FROM Products;
ID
|
Quantity
|
300
|
28
|
301
|
54
|
302
|
75
|
...
|
...
|
3. 应用程序通过游标读取 ID = 300 的行。
4. 另外一个事务使用下面的语句更新该行:
5. UPDATE Products
6. SET Quantity = Quantity - 10
WHERE ID = 300;
7. 然后应用程序通过游标将该行值更新为 (Quantity - 5)
。
8. 该行的正确的最终值是 13。如果游标预读了该行,那么该行的新值是 23。另外一个事务的更新会丢失。
在数据库应用程序中,如果预先不对行值进行验证就进行更改,那么在任何一个隔离级别都有可能丢失更新。在较高隔离级别(2 和 3),可以使用锁(读取、意图和写入锁)来确保其它事务不能对应用程序已读取的行进行更改。但在隔离级别 0 和 1,更新丢失的可能性会更大:在隔离级别 0,不能获得读取锁来防止随后的数据更改;在隔离级别 1,只能锁定当前行。使用快照隔离时不会发生更新丢失,因为任何更改旧值的尝试都会导致更新冲突。此外,在隔离级别 1 使用预取也有可能导致丢失更新,因为在客户端的预读缓冲区中应用程序定位的结果集行可能与游标中服务器定位的当前行不同。
在隔离级别 1 使用游标时,为防止丢失更新,数据库服务器支持三种不同的并发控制机制,这三个机制可由应用程序指定:
1. 读取游标中的每一行时在该行上获得意图行锁。意图锁防止其它事务在同一行上获得意图锁或写入锁,从而防止并发更新。但是,意图锁不防碍读取行锁,因此意图锁不影响并发只读语句。
2. 使用对值敏感的游标。对值敏感的游标可用于跟踪基础行发生更改或删除的时间,以便应用程序可以采取相应措施。
3. 使用 FETCH FOR UPDATE,此方法可在特定行上获得意图行锁。
指定这些替代方法的方式取决于应用程序所使用的接口。对于适用于 SELECT 语句的前两个替代方法:
· 在 ODBC 中不会发生更新丢失,因为在声明可更新游标时应用程序必须为 SQLSetStmtAttr 函数指定游标并发参数。此参数是 SQL_CONCUR_LOCK、SQL_CONCUR_VALUES、SQL CONCUR_READ_ONLY 或 SQL_CONCUR_TIMESTAMP 之一。对于 SQL_CONCUR_LOCK,数据库服务器可获取行意图锁。对于 SQL_CONCUR_VALUES 和 SQL_CONCUR_TIMESTAMP,可使用对值敏感的游标。SQL_CONCUR_READ_ONLY 用于只读游标,是缺省值。
· 在 JDBC 中语句的并发设置类似于 ODBC 中的设置。iAnywhere JDBC 驱动程序支持 JDBC 并发值 RESULTSET_CONCUR_READ_ONLY 和 RESULTSET_CONCUR_UPDATABLE。第一个值对应于 ODBC 并发设置 SQL_CONCUR_READ_ONLY,指定只读语句。第二个值对应于 ODBC SQL_CONCUR_LOCK 设置,因此使用行意图锁来防止更新丢失。请注意,在 JDBC 3.0 规范中不能直接指定对值敏感的游标。
· 在 jConnect 中,在 API 级别支持可更新游标,但底层实现(使用 TDS)不支持通过游标进行更新。jConnect 将单独的 UPDATE 语句发送到数据库服务器来更新特定行。为了避免更新丢失,应用程序必须在隔离级别 2 或更高级别运行。应用程序还可以从游标发出单独的 UPDATE 语句,但必须确保 UPDATE 语句通过在其 WHERE 子句中设置相应的条件来验证自读取该行以后该行值未变化。
· 在嵌入式 SQL 中,可通过在 SELECT 语句本身或游标声明中包括语法来设置并发说明。在 SELECT 语句中,语法 SELECT ...FOR UPDATE BY LOCK 导致数据库服务器在结果集上获取意图行锁。
或者,SELECT ...FOR UPDATE BY [ VALUES | TIMESTAMP ] 促使数据库服务器将游标类型更改为对值敏感的游标,这样如果自上次读取特定行以后通过游标对该行进行了更改,在使用 FETCH 语句时应用程序会收到警告 (SQLE_ROW_UPDATED_WARNING),在使用 UPDATE WHERE CURRENT OF 语句时应用程序会收到错误 (SQLE_ROW_UPDATED_SINCE_READ)。如果删除行,应用程序也会收到错误 (SQLE_NO_CURRENT_ROW)。
嵌入式 SQL 和 ODBC 接口也支持 FETCH FOR UPDATE 功能,虽然细节方面因所使用的 API 而不同。
在嵌入式 SQL 中,应用程序使用 FETCH FOR UPDATE,而非 FETCH,促使在该行上获取意图锁。在 ODBC 中,应用程序使用 API 调用 SQLSetPos,并使用操作参数 SQL_POSITION 或 SQL_REFRESH 和锁类型参数 SQL_LOCK_EXCLUSIVE,以在行上获取意图锁。在 SQL Anywhere 中,这些锁是长期锁,会一直保持到提交或回退事务。
分享到:
相关推荐
Serializable 隔离级别可以避免脏读、不可重复读、虚读和第二类丢失更新等问题,但是它的代价是性能开销较高。 二、Repeatable Read 隔离级别 Repeatable Read 隔离级别是第二高级别的隔离级别,它可以避免脏读和...
更新丢失(Lost update):两个事务都同时更新一行数据但是第二个事务却中途失败退出导致对数据两个修改都失效了这是系统没有执行任何锁操作因此并发事务并没有被隔离开来 2. 脏读取(Dirty Reads):一个事务开始...
隔离性可以通过不一样的配置达到不一样的隔离级别。 持久性(Durability):持久性指对于任意已提交事务,系统必须保证该事务对数据库的改变不被丢失,即使数据库出现故障。 2. 隔离级别 Serializable(串行化):可...
对于数据库而言,时刻都是多个事务同时访问同一记录的情况,这样引起数据出现不一致的情况,便是数据库的丢失更新问题(Lose update)问题。应该说,隔离级别是数据库的概念,有些难度,所以在使用它之前应该先了解...
这篇数据库教程SQLServer 事务的隔离级别,教程操作方法: 数据库是要被广大客户所共享访问的,那么在数据库操作过程中很可能出现以下几种不确定情况。 更新丢失(Lost update) 两个事务都同时更新一行数据...
并发处理带来的问题中,更新丢失可以完全避免,由应用对数据加锁即可。脏读、不可重读度、幻读,其实都是数据库的一致性问题,必须由一定的事务隔离机制来解决。性能高和事务完全隔离性无法同时满足,DB提供了4项...
仅从ACID或非ACID角度考虑问题是不够的,你应知道你的数据库支持何种事务隔离级别。一些数据库宣称自己具有“最终一致性”,但却可能对重复查询返回不一致的结果。相比于你所寻求的数据库,一些数据库提供更高的事务...
并发访问问题 事务隔离级别 丢失修改 MySQL 所有事务隔离级别在数据库层面上均可避免 脏读 READ-COMMITTED 事务隔离级别以上可避免 不可重复读 REPEATABLE-READ 事务隔离级别以上可避免 幻读 SERIALIZABLE 事务隔离...
深圳精敏工业级别20点I/O工控板JMDM-12DIO8AIOrar,一、简介 JMDM-12DIO8AIO是深圳市精敏数字机器有限公司自主研发的一款具有8路光电隔离数字量输入和4路模拟量输入,4路继电器输出和4路模拟量输出,高可靠稳定性的...
实验要求: 1.采用实验一的建库脚本和数据插入脚本创建... 分别设置不同的隔离级别, 让两个并发事务交错执行的程序或事务,能分别显示每种隔离级别下,是否出现丢失更新,脏读,读值不可复现以及幻象记录四种情况。
彻底搞清楚4种事务隔离级别:READ_UNCOMMITTED 读未提交隔离级别、READ_COMMITTED 读已提交隔离级别、REPEATABLE_READ 可重复度隔离级别、SERIALIZABLE 序列化隔离级别 彻底搞清楚MySQL的各种锁:行锁、表锁、共享锁...
目录线程安全new 和 make调度器G-P-M模型垃圾...typetabletypepossible_keysKeykey_lenrefrowsExtra事务事务的隔离级别第一类丢失更新(Lost Update)脏读不可重复读第二类丢失更新幻读隔离级别读未提交(Read Uncommit
跟隔离级别相关,如read committed,一个事务只能读到已经提交的修改。 持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。...
MySQL Cluster的数据更新使用读已提交隔离级别(read-committed isolation)来保证所有节点数据的一致性,使用两阶段提交机制(two-phased commit)保证所有节点都有相同的数据(如果任何一个写操作失败,则更新失败...
跟隔离级别相关,如read committed,一个事务只能读到已经提交的修改。 持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。 ...
12.1.3 利用子查询更新多行的值 237 12.1.4 依据外表值更新数据 238 12.1.5 分步更新表 239 12.2 删除表中的数据 240 12.2.1 delete语句基本语法 240 12.2.2 delete语句删除单行数据 240 12.2.3 delete语句...
21.3.1 在mysql.exe程序中设置隔离级别 21.3.2 在应用程序中设置隔离级别 21.4 在应用程序中采用悲观锁 21.4.1 利用数据库系统的独占锁来实现悲观锁 21.4.2 由应用程序实现悲观锁 21.5 利用Hibernate的...
4)程序及数据存储器:32K程序存储器,用于存放数据,30K数据存储器也可以用来保存数据,断电数据不丢失;6)输出:JMDM-COM40MR:40路光电隔离继电器输出,输出电压为0~220V,最大输出电流为5A, 输出口状态可回读;...
指数 执行快速SQL 执行模板提交变更回滚更改切换自动提交设置隔离级别设置Deferrable(仅PostgreSQL) 设置为只读(仅适用于PostgreSQL) 打开结果窗口公开文件报告问题连接问题设定值存储的连接在执行时设置语法...