찾다

 >  Q&A  >  본문

java - 事务 与 更新丢失的问题?

先查询某一行的值,然后在更新这个值。在高并发的情况下,A 用户 查出来的值比如是 8,这时候按着8进行处理过程中,有另外的用户B,将这个值改成了10,当A用户再去更新的时候,就会造成数据的更新丢失。

通过对查询更新方法设置事务,加入防重复读的隔离级别,也是解决不了更新丢失问题的。防重复读,只能保证第一次读到是8,后面在怎么读这条记录,结果都是8。

解决这个问题,在mysql 数据库层面,只有用for update (悲观锁)或是乐观锁来锁住这一行记录。

问题是,对于事务与mysql悲观锁的理解有点混沌了。请高人给指点迷津。

高洛峰高洛峰2888일 전551

모든 응답(4)나는 대답할 것이다

  • 大家讲道理

    大家讲道理2017-04-18 10:31:12

    트랜잭션 상태에서 mysql의 기본 격리 수준을 활성화하면 이미 이 문제를 해결할 수 있습니다.

    회신하다
    0
  • 阿神

    阿神2017-04-18 10:31:12

    예를 들어
    SET AUTOCOMMIT=0;
    WHERE id=3 FOR UPDATE 수량 선택;
    UPDATE 제품 SET 수량 = '1' WHERE id=3; 일 ;

    모든 것을 활성화할 수 있습니다.

    그런 다음 이 레코드를 읽을 때 FOR UPDATE를 추가하고 이 레코드를 잠급니다.
    FOR UPDATE를 사용하려면 트랜잭션을 사용해야 합니다. 트랜잭션을 사용하지 않는 것은 FOR UPDATE를 사용하지 않는 것과 유사하기 때문입니다. 트랜잭션에서 FOR UPDATE를 사용한 후, 이전에 COMMIT/ROLLBACK,
    다른 세션이 id=3으로 이 행을 읽는 경우 영원히 기다리고 트랜잭션이 끝날 때까지 기다린 다음 새 행
    을 읽고 FOR UPDATE를 읽습니다. id = xx를 사용하는 것이 가장 좋습니다. 또는 (xx,xx)의 ID입니다. 그렇지 않으면 데이터베이스가 잠금 테이블로 다운그레이드됩니다

    회신하다
    0
  • PHPz

    PHPz2017-04-18 10:31:12

    리가 조건:

    으아악

    회신하다
    0
  • 大家讲道理

    大家讲道理2017-04-18 10:31:12

    트랜잭션에는 4가지 수준이 있습니다
    커밋 읽기, 커밋되지 않은 읽기, 다시 읽기 가능, 직렬화
    필요 사항을 주의 깊게 설명해주세요. 살펴보겠습니다!

    회신하다
    0
  • 취소회신하다