请教一个锁定数据库记录的问题

时间:2022-12-11 18:55:12
问题是这样的:有一个oracle数据库,多个程序都会去对它操作(insert,update,delete,select等等),我现在用jdbc连接了oracle进行操作,当我要更新某个表A的某条记录时(是先select出来相应的字段,再更具这个值进行各自相应的update),是不是要把它锁定阿,以免在select与update之间其他程序也对此条记录进行操作,导致数据不一致?在c中用select 。。。for update 可以把返回的结果记录集合都锁定。在java中,该怎么搞呢?也是这样吗?谢谢

13 个解决方案

#1


嘿嘿,放心吧~~

oracle有一种并发(锁)机制--排它锁,它会帮你解决这个问题的。但也可以自己手动去设置,但比较耗资源,而且可能会有很多不知道的问题 ...

#2


和java无关.
只和数据库相关 . for update就是只有你能更新,别人不能更新.

#3


我种情况我认为用存储过程处理比较好

#4


java中也有事务处理,把这些操作封装在一个事务里即可。

#5


java中我还不会用事务,这个要学一下先!
对于用select...for update来取得记录集,报oracle 的1002错误,好奇怪.
另外可能会出现select...for update 嵌套的情况,因为有3层循环.那么当里层的进行commit,或者rollback进行释放锁的时候,是不是外层的原先被锁定的记录也被释放了阿?
谢谢.现在对oracle的锁了解还不够深入!

#6


上面的问题解决了,1002的问题也解决了。现在问题是这样的,希望大牛指点一下:
我用select...for update的时候,其他线程虽然没法对这些数据进行更改,但是还是可以select的,所以还是会出现“丢失更新”的情况,请教如何解决这个问题???万分谢谢了
丢失更新:甲乙同时开始都查到帐户内为200元,甲先开始取款100元提交,乙也取款100元提交。最终帐户余额为100元。这就是丢失更新的问题。

#7


在update时再在where条件中加上一个判断该字段的值是否还是原先查出来的值

#8


我也试了设置事务隔离的级别:对于TRANSACTION_READ_COMMITTED是不行的,对于TRANSACTION_SERIALIZABLE是可以的(当乙也提交的时候,它会报can't serialize access for this transaction异常,解决了丢失更新的问题),但是我这边jdbc无法设置TRANSACTION_REPEATABLE_READ这个级别的,oracle说无效的事务隔离级别,因此没试验这个情况,看介绍应该也无法解决丢失更新的情况,不知道如何开启下?谢谢高手指点下,问题比较的紧急

#9


to:bobfang 
你的这个办法可以,但是要这么处理的话,sql语句要该的地方比较多,因为好多程序都是以前存在的,而且也不是我负责的。我现在就是想能够在我自己负责的这部分线程处理的时候,把自己的事务隔离开来,不受其他线程的打扰,包括select。不知道有没有好的办法?

#10


如果查询后的值需要做update,最好都采用select ... for update,这样才能确保数据一致。如果仅仅你负责的部分这样处理,而别人按别的方式做,必然会出现数据异常。

#11


是的,其他别人的程序都没用for update机制(因为以前不需要这个控制),现在要改的话改的就比较多了。如果用for update机制是可以解决这个问题。
那大哥,您的意思是不是光把我的事务隔离开来没有什么办法了吗?用TRANSACTION_REPEATABLE_READ这个事务级别可以吗?jdbc如何打开这个事务隔离级别呢?再次谢谢了

#12


TRANSACTION_REPEATABLE_READ这个事务级别是指在一个事务内看到的数据始终是一致的,如在事务1开始后看到表A有一条记录,之后其他事务又向A表插入了一条记录,但只有事务1没有结束,再次查询表A还是只有一条记录。

#13


哦,看jdk文档TRANSACTION_REPEATABLE_READ这个能解决不可重复读问题,但按照您的意思还是无法解决丢失更新的问题了?那等于说现在总结出来的总共有2中方法了:1,在where中加上之前的条件;2,都用select...for update(都这样,容易产生死锁,如果程序控制不好,比如说一个事务更新了表A,要更新表B,另一个事务更新了表B,要更新表A。都还没提交,都无法访问)。


对于用TRANSACTION_SERIALIZABLE这个事务级别,我网上查资料都说效率影响很大,因为事务都是串行运行了。但是不知道具体有多少影响?小弟对这个概念不是很深刻?大哥不忙的话能说说吗?

#1


嘿嘿,放心吧~~

oracle有一种并发(锁)机制--排它锁,它会帮你解决这个问题的。但也可以自己手动去设置,但比较耗资源,而且可能会有很多不知道的问题 ...

#2


和java无关.
只和数据库相关 . for update就是只有你能更新,别人不能更新.

#3


我种情况我认为用存储过程处理比较好

#4


java中也有事务处理,把这些操作封装在一个事务里即可。

#5


java中我还不会用事务,这个要学一下先!
对于用select...for update来取得记录集,报oracle 的1002错误,好奇怪.
另外可能会出现select...for update 嵌套的情况,因为有3层循环.那么当里层的进行commit,或者rollback进行释放锁的时候,是不是外层的原先被锁定的记录也被释放了阿?
谢谢.现在对oracle的锁了解还不够深入!

#6


上面的问题解决了,1002的问题也解决了。现在问题是这样的,希望大牛指点一下:
我用select...for update的时候,其他线程虽然没法对这些数据进行更改,但是还是可以select的,所以还是会出现“丢失更新”的情况,请教如何解决这个问题???万分谢谢了
丢失更新:甲乙同时开始都查到帐户内为200元,甲先开始取款100元提交,乙也取款100元提交。最终帐户余额为100元。这就是丢失更新的问题。

#7


在update时再在where条件中加上一个判断该字段的值是否还是原先查出来的值

#8


我也试了设置事务隔离的级别:对于TRANSACTION_READ_COMMITTED是不行的,对于TRANSACTION_SERIALIZABLE是可以的(当乙也提交的时候,它会报can't serialize access for this transaction异常,解决了丢失更新的问题),但是我这边jdbc无法设置TRANSACTION_REPEATABLE_READ这个级别的,oracle说无效的事务隔离级别,因此没试验这个情况,看介绍应该也无法解决丢失更新的情况,不知道如何开启下?谢谢高手指点下,问题比较的紧急

#9


to:bobfang 
你的这个办法可以,但是要这么处理的话,sql语句要该的地方比较多,因为好多程序都是以前存在的,而且也不是我负责的。我现在就是想能够在我自己负责的这部分线程处理的时候,把自己的事务隔离开来,不受其他线程的打扰,包括select。不知道有没有好的办法?

#10


如果查询后的值需要做update,最好都采用select ... for update,这样才能确保数据一致。如果仅仅你负责的部分这样处理,而别人按别的方式做,必然会出现数据异常。

#11


是的,其他别人的程序都没用for update机制(因为以前不需要这个控制),现在要改的话改的就比较多了。如果用for update机制是可以解决这个问题。
那大哥,您的意思是不是光把我的事务隔离开来没有什么办法了吗?用TRANSACTION_REPEATABLE_READ这个事务级别可以吗?jdbc如何打开这个事务隔离级别呢?再次谢谢了

#12


TRANSACTION_REPEATABLE_READ这个事务级别是指在一个事务内看到的数据始终是一致的,如在事务1开始后看到表A有一条记录,之后其他事务又向A表插入了一条记录,但只有事务1没有结束,再次查询表A还是只有一条记录。

#13


哦,看jdk文档TRANSACTION_REPEATABLE_READ这个能解决不可重复读问题,但按照您的意思还是无法解决丢失更新的问题了?那等于说现在总结出来的总共有2中方法了:1,在where中加上之前的条件;2,都用select...for update(都这样,容易产生死锁,如果程序控制不好,比如说一个事务更新了表A,要更新表B,另一个事务更新了表B,要更新表A。都还没提交,都无法访问)。


对于用TRANSACTION_SERIALIZABLE这个事务级别,我网上查资料都说效率影响很大,因为事务都是串行运行了。但是不知道具体有多少影响?小弟对这个概念不是很深刻?大哥不忙的话能说说吗?