1. 전파(트랜잭션의 전파 속성)
전파: 키 속성은 프록시가 트랜잭션 동작을 추가해야 하는 메서드를 결정합니다. 이러한 속성의 가장 중요한 부분은 전파 동작입니다. 다음 옵션을 사용할 수 있습니다. PROPAGATION_REQUIRED--현재 트랜잭션을 지원합니다. 현재 트랜잭션이 없으면 새 트랜잭션을 만듭니다. 이것은 가장 일반적인 선택입니다.
PROPAGATION_SUPPORTS--현재 트랜잭션을 지원합니다. 현재 트랜잭션이 없으면 비트랜잭션 방식으로 실행됩니다.
PROPAGATION_MANDATORY--현재 트랜잭션을 지원합니다. 현재 트랜잭션이 없으면 예외가 발생합니다.
PROPAGATION_REQUIRES_NEW--새 트랜잭션을 생성합니다. 현재 트랜잭션이 있으면 현재 트랜잭션을 일시 중지합니다.
PROPAGATION_NOT_SUPPORTED--비트랜잭션 방식으로 작업을 실행합니다. 현재 트랜잭션이 있으면 현재 트랜잭션을 일시 중단합니다.
PROPAGATION_NEVER--비 트랜잭션 방식으로 실행하고 트랜잭션이 현재 존재하는 경우 예외를 발생시킵니다.
1: PROPAGATION_REQUIRED는 현재 실행되고 있는 다른 트랜잭션 에 속하지 않은 트랜잭션을
조인한 후 새로운 트랜잭션을 시작한다. 이미 시작됨 트랜잭션이 완료된 후 이때 ServiceB.methodB가 호출되고 ServiceB.methodB는 ServiceA.methodA의 트랜잭션 내부에서 이미 실행 중임을 확인하므로 새 트랜잭션을 시작하지 않습니다. 그리고 ServiceA.methodA가 실행 중일 때 자신이 트랜잭션에 없음을 발견하면 자신에게 트랜잭션을 할당합니다. 이런 식으로 ServiceA.methodA 또는 ServiceB.methodB 어디에서나 예외가 발생하면 트랜잭션이 롤백됩니다. ServiceB.methodB의 트랜잭션이 커밋되더라도 다음 실패 시 ServiceA.methodA가 롤백되고 ServiceB.methodB가 롤백됩니다.
2: PROPAGATION_SUPPORTS가
현재 트랜잭션에 있으면 트랜잭션으로 실행되고 현재 트랜잭션에 없으면 논트랜잭션으로 실행
3: PROPAGATION_MANDATORY는
트랜잭션에서 실행되어야 합니다. 즉, 하나의 상위 트랜잭션에서만 호출할 수 있습니다. 그렇지 않으면 그는 예외를 던질 것입니다
4: PROPAGATION_REQUIRES_NEW
이것은 더 복잡합니다. 예를 들어 ServiceA.methodA의 트랜잭션 수준을 PROPAGATION_REQUIRED로, ServiceB.methodB의 트랜잭션 수준을 PROPAGATION_REQUIRES_NEW로 설계하면 ServiceB.methodB가
실행될 때 ServiceA.methodA가 위치한 트랜잭션이 일시 중지되고 ServiceB.methodB는 새 트랜잭션을 시작합니다. 트랜잭션,
계속 실행하기 전에 ServiceB.methodB의 트랜잭션이 완료될 때까지 기다립니다 . 그와 PROPAGATION_REQUIRED의 차이점은 트랜잭션 롤백 정도입니다.
ServiceB.methodB는 새 트랜잭션이므로 두 가지 트랜잭션이 있습니다 . ServiceB.methodB가 제출된 경우 ServiceA.methodA는 롤백에 실패하고 ServiceB.methodB는 롤백되지 않습니다. ServiceB.methodB가 실패하고 롤백되는 경우
발생하는 예외가 ServiceA.methodA에 의해 포착되면 ServiceA.methodA 트랜잭션이 여전히 커밋될 수 있습니다.
5: PROPAGATION_NOT_SUPPORTED는
현재 트랜잭션을 지원하지 않습니다. 예를 들어 ServiceA.methodA의 트랜잭션 수준이 PROPAGATION_REQUIRED이고 ServiceB.methodB의 트랜잭션 수준이 PROPAGATION_NOT_SUPPORTED
이면 ServiceB.methodB가 실행될 때 ServiceA.methodA의 트랜잭션이 일시 중지되고 비트랜잭션 상태로 실행됩니다. , 그런 다음 ServiceA .methodA의 트랜잭션을 계속합니다.
6:
트랜잭션에서 PROPAGATION_NEVER를 실행할 수 없습니다. ServiceA.methodA의 트랜잭션 수준이 PROPAGATION_REQUIRED이고 ServiceB.methodB의 트랜잭션 수준이 PROPAGATION_NEVER라고 가정
하면 ServiceB.methodB에서 예외가 발생합니다.
7: PROPAGATION_NESTED
Nested를 이해하는 열쇠는 저장점입니다. 그와 PROPAGATION_REQUIRES_NEW의 차이점은 PROPAGATION_REQUIRES_NEW가 그의 상위 트랜잭션과 독립적인 새 트랜잭션을 시작하는
반면 Nested의 트랜잭션은 그의 상위 트랜잭션에 종속되고 그의 커밋은 그의 상위 트랜잭션과 함께 제출된다는 것입니다. 즉, 상위 트랜잭션이 마지막에 롤백되면 해당 트랜잭션도 롤백됩니다.
중첩 트랜잭션의 장점은 저장점이 있다는 것입니다.
*******************************************
서비스A {
/**
* 트랜잭션 속성은 PROPAGATION_REQUIRED로 구성됩니다.
*/
void methodA() { try { //savepoint ServiceB.methodB(); //PROPAGATION_NESTED level } catch (SomeException) { // ServiceC.methodC와 같은 다른 서비스 실행 (); } }
}
********************************************
也就是说ServiceB.methodB失败回滚,那么ServiceA.methodA也会回滚到savepoint点上,ServiceA.methodA可以选择另外一个分支,比如
ServiceC.methodC,继续执行,来尝试完成自己的事务。
但是这个事务并没有在EJB标准中定义。
Spring事务的隔离级别
1. ISOLATION_DEFAULT: 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.
另外四个与JDBC的隔离级别相对应
2. ISOLATION_READ_UNCOMMITTED: 这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。
这种隔离级别会产生脏读,不可重复读和幻像读。
3. ISOLATION_READ_COMMITTED: 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据
4. ISOLATION_REPEATABLE_READ: 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。
它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。
5. ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。
除了防止脏读,不可重复读外,还避免了幻像读。
什么是脏数据,脏读,不可重复读,幻觉读?
脏读: 指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,
另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据, 那么另外一
个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。
不可重复读: 指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。
那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的数据
可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。
幻觉读: 指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及
到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,
以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。