我在程序里使用了select ...for update对oracle数据库中某条记录进行锁定,在调试程序的时候为了验证行锁的可行性,在对此条记录进行commit或rollback操作之前将程序停止,此时此记录应该是被锁定了,再次启动程序的时候,我期望的是当程序执行到select ...for update的时候会有记录被锁定的相应提示,但结果是程序执行的很顺利,没有任何异常;但另一方面,我用toad连接oracle,同时打开两个toad,在其一执行语句select ...for update,在commit之前,在另外一个toad里再次执行此条语句,会有错误提示:资源正忙...,这正是期望的结果。请问各位高手,为什么在程序里不能和toad里有一致的结果呢?
你需要启动2个应用程序才行啊,你不都启动了2个toad客户端了嘛!
你启动程序(假设为会话A)执行select xx from table where ... for update;将相应的行锁住;这时在另一程序中启动(假设为会话B)执行select xx from table where for update nowait;
这样如果会话A锁住了那一行,会话B则会因为锁而立即给予提示信息不会处于等待状态!这时你可以看到你的程序的提示信息:resource busy and acquire with NOWAIT specified
如果是update语句,应该是不能执行的。不知道是不是LZ没有正确判断ora的报错(sqlca.sqlcode)?导致程序无任何异常(实际上已经报错)
同意,你的程序退出的话,session结束,会自动rollback释放锁。
第二个客户端启动后,是会被锁的!而你把第一个客户端停止了,当然已经把第一个客户端的锁给释放了啊!第二个客户端执行select 。。 for update当然不会被锁了
这里的链接指的是程序中获取的数据库Connection,把程序停止时,这个线程结束了,相应的链接回收,行级锁同时也被释放。再次启动程序时属于正常的锁定。
估计和连接池有关.虽然ORACLE看到SESSION仍然存在,但是客户端其实已经CLOSE,虽然程序没有ROLLBACK, ORACLE会自动ROLLBACK. 建议你暂时屏蔽 close()方法来试验.泡这个版面的人,基本都是从纯粹ORACLE的角度谈问题.
这点oracle 和其它数据不一样
没有用asp.net,不过用过java,asp.net里有没有自动提交的设置了,java里是有的,setAutoCommit(true)就是自动提交了。不需要通过commit叻