多线程并发操作数据库时报读写冲突的错误
2011-04-08 17:29
465 查看
【解决方案一】
要提升SQL的查詢效能,一般來說大家會以建立索引(index)為第一考量。其實除了index的建立之外,當我們在下SQL Command時,在語法中加一段WITH (NOLOCK)可以改善線上大量查詢的環境中資料集被LOCK的現象藉此改善查詢的效能。
不過有一點千萬要注意的就是,WITH (NOLOCK)的SQL SELECT有可能會造成Dirty Read。
例如:
SELECT COUNT(UserID)
FROM EMPLOYEE WITH (NOLOCK)
JOIN WORKING_GROUP WITH (NOLOCK) ON
EMPLOYEE.UserID = WORKING_GROUP.UserID
因為SQL Server會執行對應的鎖定一致性檢查。
欲改善整體資料庫查詢的效能,請將WITH (NOLOCK)加在您的SELECT語法中Table名稱的後面,雖然(NOLOCK)也可以,但是微軟還是建議大家要加WITH。
除了簡單的SELECT之外,有JOIN的SELECT語法也是可以使用的。但是DELETE、INSERT、UPDATE這些需要transaction的指令就不行了…
有些文件說,加了WITH (NOLOCK)的SQL查詢效率可以增加33%。
加了WITH (NOLOCK)即告訴SQL Server,我們的這段SELECT指令無需去考慮目前table的transaction lock狀態,因此效能上會有明顯的提升,而且資料庫系統的Lock現象會有明顯的減少(包含Dead Lock)。
有一點要特別注意,因為WITH (NOLOCK)不考慮目前table的transaction lock,因此當有某些資料正處於多個phase交易(例如跨多個table的transaction交易-->如提款系統),
WITH (NOLOCK)會讓目前處理交易process的資料被忽略…
講白話一點,也就是說當使用NoLock時,它允許閱讀那些已經修改但是還沒有交易完成的資料。因此如果有需要考量transaction交易資料的即時完整性時,使用WITH (NOLOCK)就要好好考慮一下。
如果不需考量transaction,WITH (NOLOCK)或許是個好用的參考。
註1:WITH ( < table_hint > )
指定由查詢最佳化器使用的資料表掃描、一或多個索引,
或由查詢最佳化器利用此資料表以及為此陳述式使用鎖定模式。
註2:WITH (NOLOCK)相當於READ UNCOMMITTED
【解决方案二】
常见的并发问题,使用锁和事务来控制
【总结】
多线程程序去读写数据库,首先该数据库须支持并发访问,如果支持就要考虑并发控制的问题,根据自己需求可以决定是否使用with(lock),或者通过锁或者事务机制去解决。
要提升SQL的查詢效能,一般來說大家會以建立索引(index)為第一考量。其實除了index的建立之外,當我們在下SQL Command時,在語法中加一段WITH (NOLOCK)可以改善線上大量查詢的環境中資料集被LOCK的現象藉此改善查詢的效能。
不過有一點千萬要注意的就是,WITH (NOLOCK)的SQL SELECT有可能會造成Dirty Read。
例如:
SELECT COUNT(UserID)
FROM EMPLOYEE WITH (NOLOCK)
JOIN WORKING_GROUP WITH (NOLOCK) ON
EMPLOYEE.UserID = WORKING_GROUP.UserID
因為SQL Server會執行對應的鎖定一致性檢查。
欲改善整體資料庫查詢的效能,請將WITH (NOLOCK)加在您的SELECT語法中Table名稱的後面,雖然(NOLOCK)也可以,但是微軟還是建議大家要加WITH。
除了簡單的SELECT之外,有JOIN的SELECT語法也是可以使用的。但是DELETE、INSERT、UPDATE這些需要transaction的指令就不行了…
有些文件說,加了WITH (NOLOCK)的SQL查詢效率可以增加33%。
加了WITH (NOLOCK)即告訴SQL Server,我們的這段SELECT指令無需去考慮目前table的transaction lock狀態,因此效能上會有明顯的提升,而且資料庫系統的Lock現象會有明顯的減少(包含Dead Lock)。
有一點要特別注意,因為WITH (NOLOCK)不考慮目前table的transaction lock,因此當有某些資料正處於多個phase交易(例如跨多個table的transaction交易-->如提款系統),
WITH (NOLOCK)會讓目前處理交易process的資料被忽略…
講白話一點,也就是說當使用NoLock時,它允許閱讀那些已經修改但是還沒有交易完成的資料。因此如果有需要考量transaction交易資料的即時完整性時,使用WITH (NOLOCK)就要好好考慮一下。
如果不需考量transaction,WITH (NOLOCK)或許是個好用的參考。
註1:WITH ( < table_hint > )
指定由查詢最佳化器使用的資料表掃描、一或多個索引,
或由查詢最佳化器利用此資料表以及為此陳述式使用鎖定模式。
註2:WITH (NOLOCK)相當於READ UNCOMMITTED
【解决方案二】
常见的并发问题,使用锁和事务来控制
【总结】
多线程程序去读写数据库,首先该数据库须支持并发访问,如果支持就要考虑并发控制的问题,根据自己需求可以决定是否使用with(lock),或者通过锁或者事务机制去解决。
相关文章推荐
- VC编译没有错误,exe文件操作数据库(ADO/MDB)时报错,解决方法
- VB+ADO检测数据库并发操作和处理并解决并发冲突
- 多线程协作 FileStream文件读写操作,读写冲突解决
- 操作数据库时报“无效的列索引”错误
- 多线程实现数据库的并发操作
- VB+ADO检测数据库并发操作和处理并解决并发冲突
- 多线程实现数据库的并发操作
- VC编译没有错误,exe文件操作数据库时报错,No value given for one or more required parameters
- 多线程时控制并发数据库操作的思路
- delphi 下多线程 并发操作 数据库(数据库锁) 注意事项
- VB+ADO检测数据库并发操作和处理并解决并发冲突
- Android SQLite数据库(事务)的使用,多线程CRUD并发操作(可用于实际开发)
- 操作数据库时报“无效的列索引”错误,超出游标最大值
- wp7 操作sqlite 时报 不能打开数据库的错误
- VB+ADO检测数据库并发操作和处理并解决并发冲突
- 多线程并发操作数据库以及数据库升级
- Java多线程并发锁和原子操作,你真的了解吗?
- sqlserver备份还原数据库时报占用错误
- 纯C++ 连接SQL Server2005 数据库读写操作的小例子
- 一个常见数据库操作错误的分析(一)