大家好
    我现在要建一个存储过程a,每天00:00运行一次,a需要用到数据表b的数据
但是,应用程序c在a运行期间,有可能会往表b写数据,
问题:a会锁定b吗?
如果锁定,c只能等到a运行完?
如果不锁定,00:00:50时,应用程序改了100条记录,这时存储过程计算的就是改后的,而这些修改后的,将在明天的过程再被计算一次。
你们都是怎么处理的?
另外,如果我想知道,好多存储过程同时读一个表时,是并发的还是等一个读完另一个再用的?
好多存储过程同时写一个表时是不是要排队并给表加锁?
还有,要想了解这些,还有具体性能那些,有哪些比较好的书或工具?

解决方案 »

  1.   

    另外,如果我想知道,好多存储过程同时读一个表时,是并发的还是等一个读完另一个再用的?
    默认情况读数据是共享锁,也就是并发的.
     
    好多存储过程同时写一个表时是不是要排队并给表加锁? 
    锁有多种粒度,可参考帮助中select语句中各种锁的说明.
    还有帮助中有关事务隔离级别的部分.
      

  2.   

    锁的帮助说明
    语法
    < table_hint > ::=
        { INDEX ( index_val [ ,...n ] )
            | FASTFIRSTROW
            | HOLDLOCK
            | NOLOCK
            | PAGLOCK
            | READCOMMITTED
            | READPAST
            | READUNCOMMITTED
            | REPEATABLEREAD
            | ROWLOCK
            | SERIALIZABLE
            | TABLOCK
            | TABLOCKX
            | UPDLOCK
            | XLOCK 
        } 参数
    INDEX ( index_val [ ,...n ] )指定 SQL Server 在处理语句时使用的索引的名称或 ID。只能为每个表指定一个索引提示。 如果存在聚集索引,则 INDEX(0) 强制聚集索引扫描,而 INDEX(1) 强制聚集索引扫描或查找。如果不存在聚集索引,则 INDEX(0) 强制表扫描,而 INDEX(1) 则被解释为错误。 选择性的 INDEX = 语法(用于指定单一索引提示)只受向后兼容性的支持。如果在单一提示列表中使用了多个索引,则将忽略重复项,所列出的其余索引将用于检索表中的行。索引提示中的索引顺序很重要。多索引提示还强制索引 ANDing,且 SQL Server 在所访问的每个索引上应用尽可能多的条件。如果带提示的索引集合不是覆盖性的,则在检索全部索引列后执行一次提取操作。说明  如果在星型联接的事实数据表中使用引用多个索引的索引提示,则 SQL Server 将忽略该索引提示并返回一条警告消息。此外,不允许在指定了索引提示的表上使用索引 OR 运算。 
    表提示中的最大索引数为 250 个非聚集索引。FASTFIRSTROW等同于 OPTION (FAST 1)。有关更多信息,请参见 SELECT 中 OPTION 子句的 FAST。 HOLDLOCK等同于 SERIALIZABLE。(有关更多信息,请参见本主题下面的 SERIALIZABLE。)HOLDLOCK 选项仅适用于指定了该选项的表或视图,且仅限于由它所在语句所定义的事务的时间段内。HOLDLOCK 不能用于包括 FOR BROWSE 选项的 SELECT 语句。NOLOCK等同于 READUNCOMMITTED。有关更多信息,请参见本主题后面的 READUNCOMMITTED。PAGLOCK在通常采取单个共享表锁的地方采取共享页锁。READCOMMITTED指定用与运行在 READ COMMITTED 隔离级别的事务相同的锁定语义执行扫描。有关隔离级别的更多信息,请参见 SET TRANSACTION ISOLATION LEVEL。 READPAST指定跳过(越过读取)锁定的行。例如,假设表 T1 包含单个整数列,其值为 1、2、3、4 和 5。如果事务 A 将值 3 更改为 8,但尚未提交,则 SELECT * FROM T1 (READPAST) 将生成值 1、2、4 和 5。READPAST 仅适用于在 READ COMMITTED 隔离级别操作的事务,且只越过读取行级锁。该锁提示主要用于在 SQL Server 表中实现工作队列。READUNCOMMITTED指定允许脏读。这表示不发放共享锁,也不遵守排它锁。允许脏读会导致更高的并发性,但会降低一致性。如果指定了 READUNCOMMITTED,就有可能读取未提交的事务,或读取在读取过程中回滚的一套页,因此可能出现错误信息。有关隔离级别的更多信息,请参见 SET TRANSACTION ISOLATION LEVEL。说明  如果在指定了 READUNCOMMITTED 的情况下收到 601 号错误信息,则按解决死锁错误 (1205) 的方法解决该错误,然后重试执行语句。
    REPEATABLEREAD指定用与运行在 REPEATABLE READ 隔离级别的事务相同的锁定语义执行扫描。有关隔离级别的更多信息,请参见 SET TRANSACTION ISOLATION LEVEL。ROWLOCK指定在通常采取单个共享页或表锁的情形下采取共享行锁。SERIALIZABLE等同于 HOLDLOCK。通过将共享锁保持到事务完成,使之更具有约束性(而不要不管事务是否完成,都在不再需要所需的表或数据页时就立即释放共享锁)。用与运行在 SERIALIZABLE 隔离级别的事务相同的语义执行扫描。有关隔离级别的更多信息,请参见 SET TRANSACTION ISOLATION LEVEL。TABLOCK指定在表上采取的共享锁一直保持到语句结束。如果同时指定 HOLDLOCK,那么在事务结束之前该共享表锁将一直保持。TABLOCKX指定在表上采取的排它锁一直保持到语句结束或事务结束。UPDLOCK指定读取表时采取更新锁而不是共享锁,且将这些更新锁保持到语句结束或事务结束。XLOCK指定应采取排它锁,且保持到由语句所处理的全部数据上的事务结束。如果与 PAGLOCK 或 TABLOCK 一同指定,则排它锁适用于适当的粒度级别。
      

  3.   

    事务隔离级别说明
    SET TRANSACTION ISOLATION LEVEL
    控制由连接发出的所有 Microsoft® SQL Server™ SELECT 语句的默认事务锁定行为。语法
    SET TRANSACTION ISOLATION LEVEL
        { READ COMMITTED
            | READ UNCOMMITTED
            | REPEATABLE READ
            | SERIALIZABLE 
        }参数
    READ COMMITTED指定在读取数据时控制共享锁以避免脏读,但数据可在事务结束前更改,从而产生不可重复读取或幻像数据。该选项是 SQL Server 的默认值。READ UNCOMMITTED执行脏读或 0 级隔离锁定,这表示不发出共享锁,也不接受排它锁。当设置该选项时,可以对数据执行未提交读或脏读;在事务结束前可以更改数据内的数值,行也可以出现在数据集中或从数据集消失。该选项的作用与在事务内所有语句中的所有表上设置 NOLOCK 相同。这是四个隔离级别中限制最小的级别。REPEATABLE READ锁定查询中使用的所有数据以防止其他用户更新数据,但是其他用户可以将新的幻像行插入数据集,且幻像行包括在当前事务的后续读取中。因为并发低于默认隔离级别,所以应只在必要时才使用该选项。SERIALIZABLE在数据集上放置一个范围锁,以防止其他用户在事务完成之前更新数据集或将行插入数据集内。这是四个隔离级别中限制最大的级别。因为并发级别较低,所以应只在必要时才使用该选项。该选项的作用与在事务内所有 SELECT 语句中的所有表上设置 HOLDLOCK 相同。注释
    一次只能设置这些选项中的一个,而且设置的选项将一直对那个连接保持有效,直到显式更改该选项为止。这是默认行为,除非在语句的 FROM 子句中在表级上指定优化选项。SET TRANSACTION ISOLATION LEVEL 的设置是在执行或运行时设置,而不是在分析时设置。