我在事务中执行了一个Service方法并更新了几个表。在默认隔离级别,并发更新会相互覆盖。我不希望这种情况发生,所以我正在考虑切换到REPEATABLE_READ。这样做,我明白我会尽可能从数据库驱动程序中抛出异常(使用PostgreSQL,这样就会发生)。
Spring-ish处理这个问题的方法是什么?我有点惊讶的是,似乎没有内置任何东西,但也许我没有错误地看待问题。
在我的情况下,我试图找到第一个"可用"要更新的行。我想避免两个并发事务更新同一行,但我希望最终更新一行。不合时宜的计划是围绕Service方法进行try / catch并重试X次,直到更新完成(找到要更新的行或确定没有要更新的行)。这感觉非常手动/沉重。
答案 0 :(得分:0)
一种解决方案是使用隔离级别序列化事务。线程A在线程A启动事务后修改相同记录并在线程A提交之前提交时,线程A可能抛出异常。我不知道Spring,所以我不知道你是否必须自己编写一个重试机制,或者Spring是否为你做了这个。
另一种解决方案是使用默认隔离级别(读取已提交)。添加' modification_count'列到表。当您读取记录时,您会记住记录的修改计数。更新记录时,请确保增加修改计数,并且仅在修改计数与读取记录时具有相同值时才更新。因此,当您使用modification_count = 15读取记录时,请确保更新如下:
update TABLE_NAME set value=1234, modification_count=16 where id=1234567 and modification_count=15
检查更新的行数。如果一行更新,一切都很顺利。如果udpated为零行,则另一个线程同时更新了记录。在这种情况下,您必须重试您的交易。