我有一个程序,用来收集上千个客户端上报的信息,程序本身操作很简单,就是直接执行一句update将接收到的信息更新到数据库。SQL语句是这样写的。
string sql = "update productlist with(rowlock) set size='" + strSize + "' where name='" + strName + "';
由于这些操作都是同一时间进行,现在查看日志发现经常报死锁错误:
事务(进程 ID xx)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。
每个客户端上报的name值都不相同,所以不存在同一条记录被多次update的问题。
而且上报的时间段是夜里,我查了日志,这个时间点除了我说的这个操作外,也没有其他对数据库的操作
之前没有加with(rowlock) ,我怀疑是update时锁住了整个表导致其他update报错。加了with(rowlock)报 ,按道理只加行级锁的话不会锁住整个表。但现在仍然还是报同样的错误,请问有可能是什么原因导致的呢,如何排查错误呢?
------解决思路----------------------
where 条件有索引更新时间应该不会很长。
其他用户查询时可以用with (no lock)试试!
------解决思路----------------------
表设计和索引设计编码等不合理的情况下,update会锁表,但是默认情况下是锁行的。单纯两个update不应该会死锁,顶多是阻塞,你应该还有其他非update的操作,比如中间还有select等
------解决思路----------------------
单纯的多个update除非别别的操作锁了表,单单更新操作不会变死锁吧,死锁是两个事务相互等待,但一个update除了要等之前操作完成不需要等待别的事务,理论上不会死锁哦
------解决思路----------------------
1、要看name上是否有索引,且实际执行计划是否是index seek
2、遇到update和select相互阻塞,一般被牺牲的都是select。建议select增加nolock提高并发能力;
------解决思路----------------------
使用SQL Profiler监控死锁,导出死锁XML文件,贴出来给大家看看。
------解决思路----------------------
同时是不是有别的进程在对这张表进行操作呢……光是UPDATE就出死锁真心不能理解了= -