我有2个访问db的spring bean(Bean A和B)。两个bean都在PROPAGATION_REQUIRED_NEW中,隔离级别在ORACLE db上是READ COMMITED。
Bean调用使用不同的条件在同一个表上选择(通过Hibernate)两次。 然后,为表中的每一行调用bean B以对它们进行更新。 奇怪的是,如果Bean A只对数据库进行一次调用(选择),一切正常。 我已经检查了来自dba.stackexchange的查询,并且仅在第二个"选择"在Bean A中有一个db锁。
注意:为什么不为bean B使用PROPAGATION_REQUIRED或PROPAGATION_NESTED? 我们没有使用PROPAGATION_REQUIRED因为如果其中一行失败并且PROPAGATION NESTED我们正在使用的jdbc驱动程序版本不支持它,我们不会回滚所有内容。
我目前的解决方法是让一个bean单独处理select,而main bean不会调用另外两个bean进行任何事务。我发现做"从X"中选择*真的很奇怪当我们提供锁定NONE并且我们处于READ_COMMITED时导致对表的锁定。我在这里错过了什么吗?
第一个查询:
select
temptable0_.ID as ID1_43_,
temptable0_.IDSEND as IDS2_43_,
temptable0_.DATERECEI as DAT3_43_,
temptable0_.DATEPROC as DAT4_43_,
temptable0_.STATUT as STA5_43_,
temptable0_.ERROR_TYPE as ERR6_43_,
temptable0_.CODE as COD7_43_,
temptable0_.DESCRIPTION as DES8_43_,
temptable0_.NOTIF as NOT9_43_,
temptable0_.ACTION as ACT10_43_,
temptable0_.IDCLIENT as IDC11_43_,
temptable0_.PARAM as PAR12_43_
from
TABLE_TMP temptable0_
where
temptable0_.STATUT in (
'NEW'
)
第二个查询(同一个交易(BEAN A))
select
temptable0_.ID as ID1_43_,
temptable0_.IDSEND as IDS2_43_,
temptable0_.DATERECEI as DAT3_43_,
temptable0_.DATEPROC as DAT4_43_,
temptable0_.STATUT as STA5_43_,
temptable0_.ERROR_TYPE as ERR6_43_,
temptable0_.CODE as COD7_43_,
temptable0_.DESCRIPTION as DES8_43_,
temptable0_.NOTIF as NOT9_43_,
temptable0_.ACTION as ACT10_43_,
temptable0_.IDCLIENT as IDC11_43_,
temptable0_.PARAM as PAR12_43_
from
TABLE_TMP temptable0_
where
temptable0_.STATUT in (
'ERROR'
)
更新声明(由BEAN B完成)
update
TABLE_TMP
set
IDSEND=?,
DATERECEI=?,
DATEPROC=?,
STATUT=?,
ERROR_TYPE=?,
CODE=?,
DESCRIPTION=?,
NOTIF=?,
ACTION=?,
IDCLIENT=?,
PARAM=?
where
ID=?
如果IDSEND增加,则设置DATEPROC,如果出现错误或成功,则设置STATUT和ERROR_TYPE。
答案 0 :(得分:2)
Oracle不支持READ UNCOMMITED。您使用的默认模式为READ COMMITTED
。
如果您尝试从其他会话中选择具有待处理事务更改的记录,则必须等到提交更新。