1

我正在研究数据库中潜在的并发问题,所以我去阅读了。我找到了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

4 回答 4

4

其他会话可以读取的内容取决于您如何设置数据库。在 MySQL 中,它还取决于您使用的数据库引擎。您正在寻找的术语(在 ANSI SQL 术语中)是“隔离级别”

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

请参阅MySQL 事务,第二部分 - 事务隔离级别

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

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

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

MySQL 支持 MVCC

于 2009-10-13T20:58:21.233 回答
0

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

于 2009-10-13T20:58:48.320 回答
0

那篇文章提到访问未提交的数据是数据库管理器消除的问题之一。

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

...

  • 访问未提交的数据。

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

于 2009-10-13T21:12:41.903 回答
0

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

To give a specific, I used to work on a very large e-commerce site. They used read uncommitted on reads to the store catalog, since the data was heavily accessed, infrequently changed, and not sensitive to concerns about reading uncommitted data. Any data from the catalog that was used to place an order would be re-verified anyway. This was on SQL Server 2000, which was known to have locking performance problems. On newer versions of SQL Server, the locking performance has improved, so this wouldn't be necessary.

于 2009-10-13T21:19:47.747 回答