28-Transactions Flashcards
Propagations in Transactional
- MANDATORY: throw an exception if no current txn
- NESTED: create nested transaction if current txn exists, create new txn otherwise
- NEVER: throws an exception if current txn exists
- NOT_SUPPORTED: run without txn
- REQUIRED: create new txn if not exist
- REQUIRES_NEW: create new txn if not exist. Run in new independent txn otherwise
- SUPPORTS: don’t create txn. Just use if exists
Difference between Propagation.REQUIRED_NEW and Propagation.NESTED
REQUIRED_NEW: suspend current transaction, create a new transaction which won’t affect outer transaction if fails
NESTED: create a nested transaction if the current transaction exists. Failure in the nested transaction will roll back the current one.
Isolations in Transactional
DEFAULT READ_UNCOMMITTED READ_COMMITTED REPEATABLE_READ SERIALIZABLE
___means that none of the actions taken in a transaction violate any integrity constraints (e.g. foreign key constraint)
C in ACID
Transaction APIs supported by Spring
JTA: java transaction API - distributed transaction
Hibernate
JPA
JDO
What is D in ACID?
Committed changes are permanent
Create JDBC transaction
conn = dataSource.getConnection()
conn. setAutoCommit(false)
conn. commit()
conn. rollback()
Create JMS transaction
session = conn.createSession(true, 0)
session. commit()
session. rollback()
Create JPA transaction
tx = entityManager.getTransaction()
tx. begin()
tx. commit()
tx. rollback()
Create Hibernate transaction
tx = session.beginTransaction()
tx. commit()
tx. rollback()
What is the difference between local and global transactions?
Local: single resource (e.g. db) & connection
Global: multiple resources (distributed transaction)
What is the requirement for using JTA?
JTA implementation e.g.
- Full application server (WebSphere, JBoss, WebLogic)
- Standalone implementation (Atomikos, JTOM)
What API does Spring use for the global and local transactions?
Use the same API
What is the base interface that Spring uses to abstract transaction APIs?
PlatformTransactionManager
Annotation to enable transaction in Spring. Where we should put it?
@EnableTransactionManager
Add it to a configuration class
List down 6 implementations of PlatformTransactionManager?
- DataSourceTransactionManager
- JmsTransactionManager
- JpaTransactionManager
- JtaTransactionManager
- WebLogicJtaTransactionManager
- WebSphereUowTransactionManager
Recommended bean name for transaction management bean?
transactionManager
How to create a transaction manager from a data source?
new DataSourceTransactionManager(dataSource)
Create a JTA transaction manager bean?
@Bean PlatformTransactionManager transactionManager() { return new JtaTransactionManager(); }
Get the current transaction manually
DataSourceUtils.getConnection(dataSource);
What happens if putting @Transactional to the interface?
Transaction will be applied for all methods
What happens if putting @Transactional to the class?
- Transaction will be applied for public methods only if it doesn’t implement an interface
- Apply to all interface methods if it’s a bean of an interface. For this, putting annotation to class or interface takes the same effect
Java’s @Transactional vs. Spring’s Transactional
- Also supported by Spring but fewer options
2. Should use Spring’s Transactional instead
What is the default for Transactional.propagation?
REQUIRED
When does a transaction get rolled back?
When throwing RuntimeException e.g. DataAccessException, HibernateException, etc.
or Error
How to customize the rollback behavior?
@Transactional(rollbackFor=MyCheckedException.class,
noRollbackFor={JmxException.class, MailException.class})
What happens if adding @Transactional to test methods/classes?
Transaction will be rolled back afterward
No need to clean up the database after testing
How to persist data in 1 specific test method if its class is annotated with @Transactional?
Using @Commit for that method e.g. @Transactional class TestClass { @Test @Commit testMethod() {} }
How to write transactional code manually?
return new TransactionTemplate(txManager).execute(status -> { try {} catch(SomeException e) { status.setRollbackOnly(); } });
When should use @Transactional(readOnly=true)?
To optimize performance if all queries inside are read, it will use 1 connection only.
How to prevent modified data when reading?
@Transactional(readonly=true, isolation=REPEATABLE_READ) to prevent reading modified data until transaction commits
In Spring test, how to run code before/after a transaction?
Using @BeforeTransaction e.g. class TestClass // run before and outside transaction @BeforeTransaction beforeTransaction() {} // run before and inside transaction @BeforeEach setup() {} @Test @Transactional void test() {}
How to configure transaction with @Sql
Using @Sql(config=@SqlConfig(transactionMode=***))
TransactionModes in @SqlConfig
- ISOLATED: run @Sql script in a new transaction
- INFERRED: get existing one or create new otherwise
- DEFAULT:
a. If it’s set for method –> get from @SqlConfig in class level. Use INFERRED if there is no @SqlConfig in class level
b. If it’s set for class –> it’s INFERRED
Usage of @Primary
If there’re multiple beans of the same type. The 1 with @Primary is the preference for @Autowired
How to specify transaction manager in @Transactional if there’s more than 1 txManager?
@Transactional(“name-of-tx-manager”) or
@Transactional(transactionManager=”name-of-tx-manager”)
How global transaction works?
Two-phase commit
How does @Sql work if not passing SQL file name?
Class level: ClassName.sql in the same package
Method level: ClassName.methodName.sql in the same package
What are execution phases in @Sql?
@Sql(executionPhase=BEFORE_TEST_METHOD)
@Sql(executionPhase=AFTER_TEST_METHOD)
How to config ErrorMode in @Sql
@Sql(config=@SqlConfig(errorMode=***))
ErrorModes in @SqlConfig
- DEFAULT: get from the parent (e.g. Class level), if not exist then FAIL_ON_ERROR
- FAIL_ON_ERROR
- CONTINUE_ON_ERROR
- IGNORE_FAILED_DROPS: ignore all errors from “DROP IF EXISTS”
What can we control with @SqlConfig?
- errorMode
- transactionMode
- transactionManager: bean name
- dataSource: bean name
and some others
Ways to run SQL scripts before each test?
- Using @Sql
- Create a bean of DataSourceInitializer
a. Create ResourceDatabasePopulator
b. ResourceDatabasePopulator.addScript(“init.sql”);
c. DataSourceInitializer. setDatabasePopulator(ResourceDatabasePopulator);
Which of the following exceptions, when thrown, will cause a Spring transaction rollback by default?
If no custom rollback rules apply, the transaction will roll back on RuntimeException and Error but not on checked exceptions.