First of all, you can declare [PersonService] that use the table named person.
That service will be using PersonNewService that can be changed the propagation of transaction by the user.
And then you can check the commit, rollback states.
@Service @Transactional @Slf4j public class PersonServiceImpl implements PersonService { @Autowired private PersonRepository personRepository; @Autowired private PersonNewService personNewService; @Override @Transactional public void addPerson(String name) throws Exception { Person person = new Person(); person.setName(name); personRepository.save(person); personNewService.addNewPerson("newName"); } }
@Service @Slf4j public class PersonNewServiceImpl implements PersonNewService { @Autowired private PersonRepository personRepository; @Autowired private PersonService personService; @Override @Transactional(propagation = Propagation.REQUIRES_NEW) public void addNewPerson(String newName) { Person newPerson = new Person(); newPerson.setName(newName); } }
I'm going to check the logic whether it's working fine.
When the API is called, you can see the result as below.
mysql> select * from person; +----+---------+ | id | name | +----+---------+ | 18 | dfefe | | 19 | newName | +----+---------+ 2 rows in set (0.00 sec)
By using "TransactionSynchronizationManager.getCurrentTransactionName()",
you can check that these two methods are working in different transaction each.
2017-10-08 18:06:41.383 INFO 15092 --- [nio-8080-exec-1] o.b.t.p.service.impl.PersonServiceImpl : addPerson : org.blog.test.person.service.impl.PersonServiceImpl.addPerson 2017-10-08 18:06:41.388 INFO 15092 --- [nio-8080-exec-1] o.b.t.p.s.impl.PersonNewServiceImpl : addNewPerson : org.blog.test.person.service.impl.PersonNewServiceImpl.addNewPerson
When exception occured, I will check the rollback and commit state.
Exception occured by the method 'throw new RuntimeException();'.
1. After addNewPerson is called, In addPerson,Exception occured
기존의 transaction A가 실행되고, 새로운 transaction B가 실행되고 commit된 이후,
transaction A로 다시 돌아와서 해당 transaction A가 끝나기 전 Exception이 발생한 경우입니다.
transaction A was executed, and then new transaction B is executed and committed.
After that, exception occured before transaction A ended.
In API, exception occured, however, transaction B is already committed.
So the statement in transaction B is inserted regardless of exception.
However, rollback occured in transaction A, so the statement in transaction A is not inserted to DB.
mysql> select * from person; +----+---------+ | id | name | +----+---------+ | 23 | newName | +----+---------+ 1 row in set (0.00 sec)
2. Before addNewPerson is called, In addPerson, Exception occured
Before transaction B, rollback occured in transaction A,
So there's no commit in transaction A,B both.
mysql> select * from person; Empty set (0.00 sec)
3. After addNewPerson is called, in addNewPerson, exception occured
Exception occured in transaction B, and then rollback occured in transaction B.
Transaction A also not committed.
mysql> select * from person; Empty set (0.00 sec)
4. After addNewPerson is called, exception occured in the method that is called from addNewPerson
External method is also proceed in transaction B. so all the transactions are rollbacked.
mysql> select * from person; Empty set (0.00 sec)
댓글 없음 :
댓글 쓰기