本文共 1357 字,大约阅读时间需要 4 分钟。
默认的TIL(Read Commited)下,开启事务后,会话中的更新操作会持续占有排它锁,直至事务提交或者回滚;使事务处理尽可能地短,减少持有资源的时间,尽快释放资源供其它会话使用;
读操作会对资源加共享锁,共享锁与排它锁不兼容,事务中的读操作可能被阻塞,进而导致当前会话持有资源的同时被阻塞等待,会延长事务执行的事件,增加死锁的几率;
可以把需要使用的数据先读出来,然后再开启事务; 如果无法避免,可以尝试在读操作上加表提示with(nolock)。(注意:with nolock 可能导致脏读);同(1);用户可能喝茶或抽烟去了,回话就可能一直持有资源,别人如果要使用该资源的话,就没法干活了。
有些操作会有一定的性能代价,例如SELECT….INTO在完成前会一直锁定系统表;
默认是Read Commited;可以通过SET TRANSACTION ISOLATION LEVEL来修改。
但要注意, 不同的隔离级别也可能导致副作用:(from SQL Server联机丛书)使修改的数据尽可能少,减少锁定的行数,从而减少事务之间的资源争夺;
建立合适的索引,降低锁粒度,减少事务之间的资源争夺;(当然建索引也有副作用,建得不好,会影响增删改的性能); 考虑某个操作能否重做,如果可以重做且不会导致脏数据的话(或者脏数据不影响业务数据,允许脏数据存在),可以将该操作搬到事务之外来做。譬如要物理批量删除某批记录及其对应的明细;表面上看,为了维护数据的一致性,要将这些操作放到事务里面;但其实可以不用显式使用事务:先删明细,再删主记录;不显式维护事务,如果删除失败,下次再删一次就行。(form SQL Server联机丛书):为了防止并发问题和资源问题,应小心管理隐式事务。使用隐式事务时,COMMIT 或 ROLLBACK 后的下一个 Transact-SQL 语句会自动启动一个新事务。这可能会在应用程序浏览数据时(甚至在需要用户输入时)打开一个新事务。在完成保护数据修改所需的最后一个事务之后,应关闭隐性事务,直到再次需要使用事务来保护数据修改。此过程使 SQL Server 数据库引擎 能够在应用程序浏览数据以及获取用户输入时使用自动提交模式。
另外,启用快照隔离级别后,尽管新事务不会控制锁,但是长时间运行的事务将阻止从 tempdb 中删除旧版本。
(form SQL Server联机丛书)在并发更新的可能性很小的系统中,处理“别人在您读取数据后更改了数据”的偶然错误的开销要比在读取数据时始终锁定行的开销小得多。
更好的做法是,避免使用游标。
本文转自Silent Void博客园博客,原文链接:http://www.cnblogs.com/happyhippy/archive/2010/08/07/1794728.html,如需转载请自行联系原作者