happyhippy

这个世界的问题在于聪明人充满疑惑,而傻子们坚信不疑。--罗素
1. 使事务处理尽可能地短;

    默认的TIL(Read Commited)下,开启事务后,会话中的更新操作会持续占有排它锁,直至事务提交或者回滚;使事务处理尽可能地短,减少持有资源的时间,尽快释放资源供其它会话使用;

2. 尽量避免在事务中进行读操作;

    读操作会对资源加共享锁,共享锁与排它锁不兼容,事务中的读操作可能被阻塞,进而导致当前会话持有资源的同时被阻塞等待,会延长事务执行的事件,增加死锁的几率;
    可以把需要使用的数据先读出来,然后再开启事务;
    如果无法避免,可以尝试在读操作上加表提示with(nolock)。(注意:with nolock 可能导致脏读);

3. 不要再事务过程中等待与用户的交互;

    同(1);用户可能喝茶或抽烟去了,回话就可能一直持有资源,别人如果要使用该资源的话,就没法干活了。

4. 谨慎使用无日志操作

    有些操作会有一定的性能代价,例如SELECT….INTO在完成前会一直锁定系统表;

5. 尽量使用低级的TIL

    默认是Read Commited;可以通过SET TRANSACTION ISOLATION LEVEL来修改。
    但要注意, 不同的隔离级别也可能导致副作用:(from SQL Server联机丛书)
IsolationLevel

6. 尽量使事务处理中修改的数据最少

    使修改的数据尽可能少,减少锁定的行数,从而减少事务之间的资源争夺;
    建立合适的索引,降低锁粒度,减少事务之间的资源争夺;(当然建索引也有副作用,建得不好,会影响增删改的性能);
    考虑某个操作能否重做,如果可以重做且不会导致脏数据的话(或者脏数据不影响业务数据,允许脏数据存在),可以将该操作搬到事务之外来做。譬如要物理批量删除某批记录及其对应的明细;表面上看,为了维护数据的一致性,要将这些操作放到事务里面;但其实可以不用显式使用事务:先删明细,再删主记录;不显式维护事务,如果删除失败,下次再删一次就行。

7. 除非真的需要,否则不要使用隐式事务处理,即使使用也要小心监视。

    (form SQL Server联机丛书):为了防止并发问题和资源问题,应小心管理隐式事务。使用隐式事务时,COMMIT 或 ROLLBACK 后的下一个 Transact-SQL 语句会自动启动一个新事务。这可能会在应用程序浏览数据时(甚至在需要用户输入时)打开一个新事务。在完成保护数据修改所需的最后一个事务之后,应关闭隐性事务,直到再次需要使用事务来保护数据修改。此过程使 SQL Server 数据库引擎 能够在应用程序浏览数据以及获取用户输入时使用自动提交模式。

    另外,启用快照隔离级别后,尽管新事务不会控制锁,但是长时间运行的事务将阻止从 tempdb 中删除旧版本。

8.  灵活地使用更低的游标并发选项,例如开放式并发选项。

    (form SQL Server联机丛书)在并发更新的可能性很小的系统中,处理“别人在您读取数据后更改了数据”的偶然错误的开销要比在读取数据时始终锁定行的开销小得多。
     更好的做法是,避免使用游标。

 

(以后陆续补充。。。)

posted on 2010-08-07 15:19  Silent Void  阅读(1179)  评论(0编辑  收藏  举报