未提交读?

时间:2009-10-13 20:54:56

标签: sql database concurrency read-uncommitted

我正在研究数据库中的潜在并发问题,所以我去了读。我找到了http://publib.boulder.ibm.com/infocenter/db2luw/v8/index.jsp?topic=/com.ibm.db2.udb.doc/admin/c0005267.htm,它提到了对未提交数据的访问权。

  

访问未提交的数据。   应用程序A可能会更新值   数据库和应用程序B可能   在它之前读取该值   承诺。然后,如果A的值是   没有后来承诺,但退出,   B执行的计算是   基于未提交的(并且可能是   无效的数据。

什么......我认为其他会话(相同的应用程序甚至同一个线程)可以读取尚未提交的数据?我认为只有将数据写入未提交的事务的连接/会话(我不确定我的术语)才能读取未提交的数据。

其他线程是否真的可以读取未提交的数据? 我打算使用mysql,但我可以使用sqlite

4 个答案:

答案 0 :(得分:3)

其他会话可以读取的内容取决于您设置数据库的方式。在MySQL中,它还取决于您使用的数据库引擎。您正在寻找的术语(使用ANSI SQL术语)是"isolation level"

许多数据库将默认为隔离级别,其中对未提交数据的读取将被阻止。因此,如果事务A更新表T中的记录1234,然后事务B尝试在A提交或回滚之前选择记录1234,则B将阻塞,直到A执行其中一项操作。

请参阅MySQL Transactions, Part II - Transaction Isolation Levels

一个严重的缺点是,长时间运行的事务(通常)中的批量更新操作可能会阻止许多请求。

你也可以设置它以便B看到未提交的数据,但这通常是不明智的。

或者,您可以使用名为MVCC(“多版本并发控制”)的方案,该方案将根据事务开始的时间为不同的事务提供一致的数据视图。这可以避免未提交的读取问题(读取可能回滚的数据)并且可扩展性更高,尤其是在长期事务的上下文中。

MySQL supports MVCC

答案 1 :(得分:0)

当然在SQL Server中,您必须选择这样做,它不是默认值,但如果您使用正确的隔离级别或查询提示,您可以选择读取未提交的行,这可能会导致问题和甚至理论上对同一行的双重读取。

答案 2 :(得分:0)

该文章提到对数据库管理员消除的问题之一访问未提交的数据。

  

数据库管理器控制它   访问以防止不良影响,   如:

     

...

     
      
  • 访问未提交的数据。
  •   

MySQL的InnoDB存储引擎支持多种事务隔离级别。有关详情,请参阅 http://dev.mysql.com/doc/refman/5.4/en/set-transaction.html

答案 3 :(得分:0)

对于某些数据库的某些版本,设置查询以便能够读取未提交的内容将提高性能,因为锁定减少了。这仍然需要回答安全性,可靠性和可扩展性等问题。

为了具体说明,我曾经在一个非常大的电子商务网站上工作。他们在对商店目录的读取时使用了未提交读取,因为数据被大量访问,不经常更改,并且对于读取未提交数据的担忧不敏感。无论如何,用于下订单的目录中的任何数据都将被重新验证。这是在SQL Server 2000上,已知有锁定性能问题。在较新版本的SQL Server上,锁定性能已得到改进,因此这不是必需的。