• Now all data be ready for publish, We had made our blog alive now. Haha.



  • These days CCP GFW blocked all the IPs from US and when I switch my IP in google Cloud, the disk data cannot be restore again. I have to restart my blog totally, Now the website is still building…



Spring @Transactional – isolation, propagation- Stack Overflow

Java PingBook 2 months ago (10-23) 19 0

Question

Can someone explain what isolation & propagation parameters are for in the @Transactional annotation via real-world example?

Basically when and why I should choose to change their default values.

Answer

Good question, although not a trivial one to answer.

Propagation

Defines how transactions relate to each other. Common options:

Required: Code will always run in a transaction. Creates a new transaction or reuses one if available.
Requires_new: Code will always run in a new transaction. Suspends the current transaction if one exists.

Isolation

Defines the data contract between transactions.

Read Uncommitted: Allows dirty reads.
Read Committed: Does not allow dirty reads.
Repeatable Read: If a row is read twice in the same transaction, the result will always be the same.
Serializable: Performs all transactions in a sequence.

The different levels have different performance characteristics in a multi-threaded application. I think if you understand the dirty reads concept you will be able to select a good option.

Example of when a dirty read can occur:

thread 1 thread 2
| |
write(x) |
| |
| read(x)
| |
rollback |
v v
value (x) is now dirty (incorrect)

So a sane default (if such can be claimed) could be Read Committed, which only lets you read values which have already been committed by other running transactions, in combination with a propagation level of Required. Then you can work from there if your application has other needs.

A practical example of where a new transaction will always be created when entering the provideService routine and completed when leaving:

public class FooService {
private Repository repo1;
private Repository repo2;

@Transactional(propagation=Propagation.REQUIRES_NEW)
public void provideService() {
repo1.retrieveFoo();
repo2.retrieveFoo();
}
}

Had we instead used Required, the transaction would remain open if the transaction was already open when entering the routine.
Note also that the result of a rollback could be different as several executions could take part in the same transaction.

We can easily verify the behaviour with a test and see how results differ with propagation levels:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations=”classpath:/fooService.xml”)
public class FooServiceTests {

private @Autowired TransactionManager transactionManager;
private @Autowired FooService fooService;

@Test
public void testProvideService() {
TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
fooService.provideService();
transactionManager.rollback(status);
// assert repository values are unchanged …
}

With a propagation level of

Requires new: we would expect fooService.provideService() was NOT rolled back since it created it’s own sub-transaction.
Required: we would expect everything was rolled back and the backing store was unchanged.




Copyright from PingBook Blog, If not specified, they are original. This site uses BY-NC-SAProtocol authenticated.
For reprinting, please indicate the link of the original text:Spring @Transactional – isolation, propagation- Stack Overflow
LIKE (0)
[1725641479@qq.com]
SHARE (0)
PingBook
Author:
We create, We sharing! Tag every value data your sharing
Submit comments
Cancel comments
emoji picture bold strikethrough center italic check in

Hi,you need to provide your name and email adress!

  • Name (Required)
  • Email (Required)
  • Website