Spring 격리를 테스트하는 매우 간단한 예를 만들고 있습니다. ,Spring 트랜잭션 격리가 작동하지 않음
@Service("service1")
@Transactional
public class Service1 {
private UserService userService;
private static Logger log = Logger.getLogger(Service1.class);
public void changeCredits() {
User user = userService.getUserById(1);
log.info("Service1 previous credits: " + user.getCredits());
int newCredit = user.getCredits() + 5;
user.setCredits(newCredit);
log.info("Service1 new credits: " + user.getCredits());
}
...
@Service("service2")
@Transactional
public class Service2 {
private UserService userService;
private static Logger log = Logger.getLogger(Service2.class);
public void changeCredits() {
User user = userService.getUserById(1);
log.info("Service2 previous credits: " + user.getCredits());
int newCredit = user.getCredits() + 5;
user.setCredits(newCredit);
log.info("Service2 new credits: " + user.getCredits());
}
이 코드를 실행 한 후, 나는 두 트랜잭션이 동시에 실행된다는 점을 때 볼 수 있습니다 : 나는이 개 매우 유사한 서비스 클래스를 가지고, 또한
@Service("manager1")
public class Manager1 {
private Service1 service1;
@Scheduled(fixedDelay = 15000)
public void sendScheduledCampaigns() {
service1.changeCredits();
}
...
@Service("manager2")
public class Manager2 {
private Service2 service2;
@Scheduled(fixedDelay = 15000)
public void sendScheduledCampaigns() {
service2.changeCredits();
}
...
: 나는이 개 매우 비슷한 일정의 수업을 두 트랜잭션 모두 데이터베이스에서 동일한 값을 얻고 있습니다. 그래서, 그들은 다른 하나의 수정을 무시하고 있습니다. 나는이 트랜잭션 격리에 오류가 가정 : 여기
INFO 27 Feb 2014 14:14:22 - Service1 previous credits: 0
INFO 27 Feb 2014 14:14:22 - Service2 previous credits: 0
INFO 27 Feb 2014 14:14:22 - Service1 new credits: 5
INFO 27 Feb 2014 14:14:22 - Service2 new credits: 5
크레딧 값이 10해야한다.
Feb 27, 2014 2:14:23 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8080"]
Feb 27, 2014 2:14:23 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-bio-8009"]
Feb 27, 2014 2:14:23 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 10698 ms
INFO 27 Feb 2014 14:14:37 - Service2 previous credits: 5
INFO 27 Feb 2014 14:14:37 - Service2 new credits: 10
INFO 27 Feb 2014 14:14:38 - Service1 previous credits: 10
INFO 27 Feb 2014 14:14:38 - Service1 new credits: 15
내가 MYSQL 함께 일하고 있어요 이러한 나의 작업 및 거래의 구성은 다음과 같습니다 :
<task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>
<task:executor id="myExecutor" pool-size="100"/>
<task:scheduler id="myScheduler" pool-size="100"/>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
<property name="packagesToScan" value="test.domain" />
</bean>
이 후
, 두 프로세스가 동시에 실행되지 않습니다으로는, 계산은 정상적인 것으로 시작
내 기본 격리 수준은 null입니다. 나는이에서 그것을 가지고 :
log.info("isolation: " +TransactionSynchronizationManager.getCurrentTransactionIsolationLevel());
그래서, 두 서비스의 분리 레벨을 변경하려고 :
@Service("service1")
@Transactional(isolation=Isolation.REPEATABLE_READ)
public class Service1 {
@Service("service2")
@Transactional(isolation=Isolation.REPEATABLE_READ)
public class Service2 {
결과는 여전히 잘못된 것입니다.
왜 이런 일이 발생했는지 알고 계십니까?
미리 감사드립니다.
안녕하세요 Koitoer, 답변 해 주셔서 감사합니다. 저는 트랜잭션의 격리 수준을 변경하려고했습니다. 그러나 결과는 완전히 동일합니다. @Transactional (격리 = Isolation.REPEATABLE_READ) 다른 생각 :이 작업을 수행하는 , 나는 두 서비스에서 트랜잭션 주석에 "분리 속성"을 추가? 다시 한 번 감사드립니다. –
어제 밤에 어제 밤에 thining하고 PessimisticLock과 같은 객체에서 잠금 기능을 사용했지만 객체를 검색하는 방법에 대해 확신하지 못했습니다. DAO에서 find 메소드를 사용하면 코드를 붙여 넣을 수 있습니다. 엔티티 관리자를 사용하는 경우에도 잠금 옵션과 함께 find를 사용해보십시오. – Koitoer
@GonzaloRon 이상하게도 같은 문제가 발생합니다. 모두 SERIALIZABLE로 설정했으며 spring jdbc와 함께 Postgres를 사용하고 있습니다. – deFreitas