3

Transactions are defined at the service level, as is typical.

But upon occasion we have a DAO method which requires a higher, SERIALIZABLE, isolation level.

But knowledge of whether the SERIALIZABLE isolation level is necessary is encapsulated in the DAO method, the service method need not know about this.

How can I enforce SERIALIZABLE isolation level at the DAO method level? I can't even find a way to identify what the isolation level is in Spring.

David Parks
  • 30,789
  • 47
  • 185
  • 328

1 Answers1

1

The service layer typically defines the transactional semantics.

But ... you can add the following annotation to achieve the serializable isolation level on the DAO implemenation method to achieve the effect:

@Transactional(isolation=Isolation.SERIALIZABLE,propagation=Propagation.MANDATORY)

The MANDATORY is so that the DAO method will not create a transaction if none exists. This will force all invocations to start from a service method. You can change that if desired.

Let me know how it works out.

les2
  • 14,093
  • 16
  • 59
  • 76
  • I haven't done a test yet, but I did note this comment in the documentation of TransactionDefinition: "Note that isolation level and timeout settings will not get applied unless an actual new transaction gets started." From that I would have guessed that changing isolation levels mid-stream would not be allowed, but perhaps I'm just reading this out of context. Any thought? – David Parks Apr 22 '11 at 18:30
  • Just did the test. The Isolation level is still set to READ COMMITTED inside the DAO method with @Transactional set as you described it. JDBC Statement javadocs also states that isolation level can only be set when the transaction is started, not after. For now I've just created a method that check for the isolation level and throws a RuntimeException if it's not SERIALIZABLE. But this requires an extra trip to the DB to query the current isolation level. – David Parks Apr 25 '11 at 14:41
  • why not use propagation=REQUIRES_NEW ? http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/transaction/annotation/Propagation.html#REQUIRES_NEW – les2 Apr 25 '11 at 20:11
  • the REQUIRES_NEW should force a new transaction to start ... with the specified isolation ... let me know. – les2 Apr 25 '11 at 20:12
  • Perhaps this is my lack of knowledge, but I thought that I can not use this option because I surely need the outer transaction to rollback if/when the inner transaction rolls back. If I am reading the docs correctly they say that the inner transaction may fail and rollback, but the outer transaction would commit. Or vice versa where an exception occurs in the outer transaction, but the inner transaction has already committed. One logical transaction may or may not encompass multiple DAO calls, that's something the service level knows about. This DAO just knows it needs SERIALIZABLE isolation. – David Parks Apr 26 '11 at 04:47