关于DB2的锁定问题

gdlin 2004-04-27 11:11:27
我发现DB2一个锁定的问题,在7.2 和 8.1下都出现了,可能是我方法不对。请大家帮我看看:

表T1(c1 int ,c2 int)是行锁。
Z:\>db2 select tabname,locksize from syscat.tables where tabname='T1'
TABNAME
LOCKSIZE
--------------------------------------------------------------------------------
------------------------------------------------ --------
T1
R


里面两条记录(1,1)(2,2)。设置DB CFG -》(LOCKTIMEOUT) = 10,锁定超时10秒

在一个命令窗口,输入一个update语句,但不提交它:
Z:\>db2 +c update t1 set c2=3 where c1=1
DB20000I SQL 命令成功完成。

另一个命令窗口,查询一个条件不同的记录,10秒后返回超时错误:
root:/>db2 "select * from t1 where c1=2"
SQL0911N因为死锁或超时,所以当前事务已回滚。原因代码为"68". SQLSTATE=40001
68 由于锁定超时而导致事务已回滚。

而我这两条语句非常明显的where条件是不同的,但update语句把和他条件不相干的另一行也锁定了。按理来说我update锁定的是条件是c1=1 ,而select的条件是C1=2,两个并不会产生锁的争用啊

大家可以试试。并请明家指定一条明路。谢谢!
...全文
230 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
lizzz 2004-06-15
  • 打赏
  • 举报
回复
另外加上索引应该也能解决这个问题。
lizzz 2004-06-15
  • 打赏
  • 举报
回复
这不是死锁,只是一个超时而已。
update的时候加了排他锁,这是后要进行查询的时候需要加共享锁,这当然是不允许的。改成脏读就不会有问题了。
xuletian 2004-05-02
  • 打赏
  • 举报
回复
db2是这样的,如果行上带上索引,事情就不一样了,所以update和select在where中使用有索引的列在锁方面也会带来好处,update没有索引的列使用索引检索时可以看出来。
gdlin 2004-04-28
  • 打赏
  • 举报
回复
up
gdlin 2004-04-27
  • 打赏
  • 举报
回复
而且为了防止RR隔离级别。我
db2set DB2_RR_TO_RS=YES
gdlin 2004-04-27
  • 打赏
  • 举报
回复
而且为了保证不会产生RR的隔离级别,我
db2set DB2_RR_TO_RS=YES
gdlin 2004-04-27
  • 打赏
  • 举报
回复
可以看出,当第一个语句update符合where子句的某一行的时候,这时此行持有该行的X锁,而当第二个select子句执行时,虽然它的where子句不包含第一句的where条件。但它持有整个表的IS锁。

而X锁和IS锁是不兼容的,必须等待应用程序释放锁。

这样的话,岂不是DB2在更新表中的任何一个数据的时候,只要它没有提交,那任何一个select语句都是执行不了的,除非隔离级别是UR(未提交读)。
Mr_Bean 2004-04-27
  • 打赏
  • 举报
回复
up
gdlin 2004-04-27
  • 打赏
  • 举报
回复
get snapshot for locks 结果


数据库锁定快照

数据库名 = TEST
数据库路径 = D:\DB2\NODE0000\SQL00001输入数据库别名 = TEST
保持的锁定 = 6
当前已连接的应用程序 = 2
当前正等待锁定的代理进程数 = 1
快照时间戳记 = 04/27/2004 13:06:48.464992

应用程序句柄 = 66
应用程序标识 = *LOCAL.DB2.00F047050619
序列号 = 0002
应用程序名 = db2bp.exe
CONNECT 认证标识 = ZHEN
应用程序状态 = 锁定等待
状态更改时间 = 04/27/2004 13:06:36.825686
应用程序代码页 = 1386
保持的锁定 = 3
总计等待时间(毫秒) = 11639

等待锁定的子节 = 0
挂起锁定的代理进程标识 = 59
保留锁定的应用程序标识 = *LOCAL.DB2.00F0C7045622
锁定名称 = 0x02000400040000000000000052
锁定属性 = 0x00000000
发行版标志 = 0x00000001
锁定对象类型 = 行
锁定方式 = 互斥锁定(X)
请求的锁定方式 = 下一个键共享(NS)
挂起锁定的表空间名 = USERSPACE1
挂起锁定的表模式 = ZHEN
挂起锁定的表名 = T1
锁定等待启动时间戳记 = 04/27/2004 13:06:36.825688

锁定列表
锁定名称 = 0x010000000100000001005A0056
锁定属性 = 0x00000000
发行版标志 = 0x40000000
锁定计数 = 1
挂起计数 = 0
锁定对象名 = 0
对象类型 = 内部 V 锁定
方式 = S

锁定名称 = 0x94928D848F9F949E7B89505241
锁定属性 = 0x00000000
发行版标志 = 0x40000000
锁定计数 = 1
挂起计数 = 0
锁定对象名 = 0
对象类型 = 内部 P 锁定
方式 = S

锁定名称 = 0x02000400000000000000000054
锁定属性 = 0x00000000
发行版标志 = 0x00000001
锁定计数 = 1
挂起计数 = 0
锁定对象名 = 4
对象类型 = 表
表空间名 = USERSPACE1
表模式 = ZHEN
表名 = T1
方式 = IS


应用程序句柄 = 59
应用程序标识 = *LOCAL.DB2.00F0C7045622
序列号 = 0012
应用程序名 = db2bp.exe
CONNECT 认证标识 = ZHEN
应用程序状态 = UOW 正在等待
状态更改时间 = 04/27/2004 12:58:51.555567
应用程序代码页 = 1386
保持的锁定 = 3
总计等待时间(毫秒) = 0

锁定列表
锁定名称 = 0x02000400040000000000000052
锁定属性 = 0x00000020
发行版标志 = 0x40000000
锁定计数 = 1
挂起计数 = 0
锁定对象名 = 4
对象类型 = 行
表空间名 = USERSPACE1
表模式 = ZHEN
表名 = T1
方式 = X

锁定名称 = 0x94928D848F9F949E7B89505241
锁定属性 = 0x00000000
发行版标志 = 0x40000000
锁定计数 = 1
挂起计数 = 0
锁定对象名 = 0
对象类型 = 内部 P 锁定
方式 = S

锁定名称 = 0x02000400000000000000000054
锁定属性 = 0x00000000
发行版标志 = 0x40000000
锁定计数 = 1
挂起计数 = 0
锁定对象名 = 4
对象类型 = 表
表空间名 = USERSPACE1
表模式 = ZHEN
表名 = T1
方式 = IX


目录 1. DB2 1.1. 创建一个返回结果集的存储过程\自定义函数 12 1.2. DB2 高级应用 14 1.3. 删除表数据时候出现日志已满的解决方法 24 1.4. DB2快照函数全解析 25 1.5. DB2中的22个命令小技巧 26 1.6. DB2实现类型ORACLE的一些功能 29 1.7. 字符数据类型转换的时候需要注意的问题(原) 30 1.8. 本地谓词的使用注意(原) 31 1.9. windows/Linux或Unix下查看DB2端口号 31 1.10. 尽量让fetch first n row only或者分页的时候结合optimize for n rows使用(原) 32 1.11. 格式化字符串(原) 33 1.12. 10大DB2优化技巧 33 1.13. 使用DB2的整数转换浮点小数时注意(原) 41 1.14. 使用递归制造测试数据(原) 42 1.15. 尽量使用自定义函数来代替存储过程 42 1.16. VALUES(…) 与 VALUES …的区别(原) 44 1.17. DB2的表锁和行锁 45 1.18. 修改表结构后不允许对表进行任何操作(原) 57 1.19. 解决暂挂表(原) 58 1.20. DB2LOOK语法及使用 58 导出表结构的表结构脚本 59 1.21. DB2的函数大全 64 1.22. DB2数据库为单个会话锁定技巧 64 1.23. EXISTS和COUNT(*)的使用(原) 68 1.24. 如果表比较大,进行COUNT的时候,可选择COUNT_BIG(*) 69 1.25. 序列(SEQUENCE) (原) 69 1.26. 数据的导入和导出 69 1 加载数据: 69 2 卸载数据: 70 3 在Load过程中使用的Exception 表有何作用,该如何创建?(原) 70 4如何导出(EXPORT),导入(LOAD)包含由公式生成字段的表 70 5 LOAD命令和自生成列值 72 6 用load命令和identityoverride参数向有identity列的表中装载数据后的注意事项 74 1.27. 利用快照函数查询数据库服务器本地以及远程的连接数 74 1.28. 查看SQL的执行计划 74 1.29. 如何查看数据库ABC的配置文件的内容? 75 1.30. 查看是哪张表挂起(原) 75 1.31. 导出(导入)数据库的所有表数据(db2move) 75 1.32. 备份数据库,恢复数据库 75 1.33. 建立数据库、缓冲池、表空间、表案例 77 1.34. 建立别名 78 1.35. 建立视图 78 1.36. 建立唯一性索引 78 1.37. 查看表的索引 79 1.38. 查看表 79 1.39. 建立触发器 79 1.40. 查看存储过程 79 1.41. view application 79 1.42. kill application 79 1.43. lock table(x) 79 1.44. lock table(s) 80 1.45. 列出所有的系统表 80 1.46. 列出系统数据库目录 80 1.47. 显示当前活动数据库 80 1.48. 查看命令选项 80 1.49. 表空间 80 1.50. 表空间容器 80 1.51. 如何知道SEQUENCE的状况 81 1.52. 如何知道SCHEMA的状况 81 1.53. 如何知道INDEX的状况 81 1.54. 查看装载数据库的instance 81 1.55. 创建数据库的instance 81 1.56. 创建数据库的catalog 81 1.57. 如何在命令行下执行DB2脚本(script) 82 1.58. 怎么样获取表结构以及索引的信息 82 1.59. 如果怀疑应用程序有死锁现象,如何确认是否死锁,并判断是哪些程序引起的死锁? 84 1.60. 数据库创建以后相关的目录和文件都有哪一些? 85 1.61. 自增列(IDENTITY) 86 1.62. 修改表结构的注意事项(原) 86 1.63. 可使用VALUES 来代替多个[not] in的条件语句 87 1.64. 计算数据库缓冲池的命中率公式 87 1.65. 查看表空间状态 88 1.66. UPDATE的N种用法 88 Examples 88 1.67. 查看表状态的快照命令 90 1.68. RUNSTATS的使用案例 91 1.69. Bufferpool设置过大导致数据库无法启动的解决方案 98 1.70. 查看DB2是否存在僵尸进程 98 1.71. 监控执行成本最高的SQL语句 99 1.72. 监控运行最长的SQL语句 99 1.73. 给表增加generated al

5,889

社区成员

发帖
与我相关
我的任务
社区描述
IBM DB2 是美国IBM公司开发的一套关系型数据库管理系统,它主要的运行环境为UNIX(包括IBM自家的AIX)、Linux、IBM i(旧称OS/400)、z/OS,以及Windows服务器版本
社区管理员
  • DB2
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧