1 - Logical Transaction vs Physical Transaction
@Service
public class UserService {
@Autowired
private InvoiceService invoiceService;
@Transactional
public void invoice() {
invoiceService.createPdf();
// send invoice as email, etc.
}
}
@Service
public class InvoiceService {
@Transactional
public void createPdf() {
// ...
}
}
Now in terms of database transactions, this should really just be one database transaction (i.e. getConnection() → setAutoCommit(false) → commit()). Spring calls this physical transaction
From Spring’s side however, there’s two logical transactions happening: First in UserService, the other one in InvoiceService
2 - Propagation Level
@Transactional(propagation = Propagation.REQUIRED)
@Transactional(propagation = Propagation.SUPPORTS)
@Transactional(propagation = Propagation.MANDATORY)
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Transactional(propagation = Propagation.NOT_SUPPORTED)
@Transactional(propagation = Propagation.NEVER)
@Transactional(propagation = Propagation.NESTED)|
|
My method needs a transaction, either open one for me or use an existing one |
getConnection(). setAutocommit(false). commit() |
|
|
I don’t really care if a transaction is open or not, i can work either way |
nothing to do with JDBC |
|
|
I’m not going to open up a transaction myself, but I’m going to throw exception if no one else opened one up |
nothing to do with JDBC |
|
|
I want my completely own transaction |
getConnection(). setAutocommit(false). commit() |
|
|
I really don’t like transactions, I will even try and suspend a current, running transaction |
nothing to do with JDBC |
|
|
I’m going to throw exception if someone else started up a transaction |
nothing to do with JDBC |
|
|
It sounds so complicated, but we are just talking savepoints! |
connection.setSavepoint() |