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联机丛书)
6. 尽量使事务处理中修改的数据最少
使修改的数据尽可能少,减少锁定的行数,从而减少事务之间的资源争夺;
建立合适的索引,降低锁粒度,减少事务之间的资源争夺;(当然建索引也有副作用,建得不好,会影响增删改的性能);
考虑某个操作能否重做,如果可以重做且不会导致脏数据的话(或者脏数据不影响业务数据,允许脏数据存在),可以将该操作搬到事务之外来做。譬如要物理批量删除某批记录及其对应的明细;表面上看,为了维护数据的一致性,要将这些操作放到事务里面;但其实可以不用显式使用事务:先删明细,再删主记录;不显式维护事务,如果删除失败,下次再删一次就行。
7. 除非真的需要,否则不要使用隐式事务处理,即使使用也要小心监视。
(form SQL Server联机丛书):为了防止并发问题和资源问题,应小心管理隐式事务。使用隐式事务时,COMMIT 或 ROLLBACK 后的下一个 Transact-SQL 语句会自动启动一个新事务。这可能会在应用程序浏览数据时(甚至在需要用户输入时)打开一个新事务。在完成保护数据修改所需的最后一个事务之后,应关闭隐性事务,直到再次需要使用事务来保护数据修改。此过程使 SQL Server 数据库引擎 能够在应用程序浏览数据以及获取用户输入时使用自动提交模式。
另外,启用快照隔离级别后,尽管新事务不会控制锁,但是长时间运行的事务将阻止从 tempdb 中删除旧版本。
8. 灵活地使用更低的游标并发选项,例如开放式并发选项。
(form SQL Server联机丛书)在并发更新的可能性很小的系统中,处理“别人在您读取数据后更改了数据”的偶然错误的开销要比在读取数据时始终锁定行的开销小得多。
更好的做法是,避免使用游标。
(以后陆续补充。。。)