为什么在“插入查询”locking整个表之前“开始事务”?

我写了一个存储过程来插入一条logging。 我在插入查询之上添加了“Begin Transaction”并执行查询。 我注意到,另一个应用程序正在显示一个网页与来自同一张表的logging,在插入完成时被吊死。

为什么开始事务locking整个表? 作家不应该阻止读者。 它应该默认为ON。

我正在使用SQL Server 2005 Express。 我也想知道Oracle和MySQL如何处理相同的情况。

开始事务是事务的开始 – 在结束事务之前,不能将其他数据写入表中,这是为了强制数据库上的ACID标准。 http://en.wikipedia.org/wiki/ACID

如果您需要执行多个查询,就像使用单个primefaces操作一样,则使用事务。 如果你不需要primefaces性,不要使用交易!

这是非常基本的东西 – 在尝试编写数据库代码之前,您可能需要梳理基本的数据库理论,如果您不熟悉核心原则(如事务),则可能会严重损害应用程序。

虽然其他人所说的基本上是正确的,但这种行为取决于您正在使用的事务隔离级别; 事务处理技术上不可能locking整个表。

如果您希望其他用户能够在您修改数据的同时读取您的数据,则可以将TIL设置为READ UNCOMMITED

 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITED 

当然,这个设置需要非常小心,因为这可能会导致数据不一致,这取决于其他用户在做什么。

更多信息:

http://msdn.microsoft.com/en-us/library/ms189122.aspx
http://msdn.microsoft.com/en-us/library/ms173763.aspx

那么,我不是一个SQL Server的人,所以,我不会说这个。

但是,因为这个问题被标记为“oracle”,而且海报也问到它在Oracle中是如何工作的,我会解决这个问题。

在Oracle中,默认的事务隔离级别是READ COMMITTED。 此外,Oracle 始终locking在行级别,并且永远不会将锁升级到该块(称为SQL Server中的页面)级别。

因此,如果在表中locking行“a”,然后另一个会话尝试在同一个表中locking行“b”,那么即使这些行位于同一个块中,该锁也会成功。

至于“开始交易”,在Oracle中,如果还没有开始的话,任何DML都会隐含地开始交易。 该事务将保持打开状态,直到会话显式提交或回滚,或者被终止(在这种情况下,Oracle将回滚事务)。

但是,Oracle确实有“开始事务”语法,即“设置事务”。 这可以用来开始只读或读写事务,或设置隔离级别。

只读事务的一个有趣用途是(除了只读)之外,它提供在该事务中执行的所有查询,读取与事务开始时间点的一致性。 因此,一旦您设置“只读事务”,您执行的任何查询都将返回与事务开始时间一致的结果。 (通常,查询结果与查询执行开始的时间点是一致的,但是对于只读事务,事务中执行的所有查询都将与事务的开始一致。)

作家不应该阻止读者

这仅适用于快照隔离 ,所有其他隔离级别都要求读写器阻塞写入阻止器和写入器来阻止读取器(不考虑脏读取,因为它们不一致 ,不应使用)。 如果您需要此行为,请使用行版本控制(链接包含解决scheme)。

为什么批量插入locking整个表?

这实际上可能会或可能不会是真实的。 行为受你控制:

TABLOCK

指定在批量导入操作期间获取表级锁。 如果表中没有索引并且指定了TABLOCK,则可以由多个客户端同时加载表。 默认情况下,locking行为由table lock on bulk load的表选项table lock on bulk load

有关更多详细信息,请阅读产品规格: 控制批量导入的locking行为 。