0

I've tried to implement exclusive read access to some Entity (DB table row). The intention was to force any other reader to wait with row read until previous transaction is over.

I've used @Lock(PESSIMISTIC_WRITE) from Spring Data JPA. Here is my example Entity & repository. I'm testing it with SQL Server 2022 and Hibernate 5.6

    @Entity
    class Product(
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        var id: Long? = null,
    
        var code: String,
    )
    
    interface ProductRepository : JpaRepository<Product?, Long?> {
        @Lock(PESSIMISTIC_WRITE)
        fun findByCode(code: String): Product
    
        fun getByCode(code: String): Product
    }

It works as expected when:

  • first thread reads a row using findByCode and waits before transaction is closed
  • second thread tries to read the same row using findByCode -> read is blocked (no exception - it just has to wait)

It does not work in case the second thread reads data using getByCode method, which is not annotated. I understand it like this: second thread cannot acquire another lock on the same row but nothing stops him from just reading the row (ignoring the lock of the first thread).

How could I prevent any other database user from reading my row when I am working with it?

Mamut
  • 133
  • 1
  • 10
  • multi-version concurrency control ? Apparently MS-SLQServer may use it with READ_COMMITTED_SNAPSHOT and this allows readers to fetch already blocked data. – p3consulting Jan 12 '23 at 18:08

0 Answers0