0

Je suis nouveau au printemps et apprendre les concepts de transaction. Impossible de faire fonctionner @Transactional.Printemps :: @Transactional ne fonctionne pas

Cas d'utilisation:
insertion de données des détails et des employés des employés devrait rollback quand getEmployee() renvoie RuntimeException. Mais le retour en arrière ne se produit pas. J'utilise la base de données Oracle 11g et le ressort 4.3.1.RELEASE. Ci-dessous, le code Java autonome est en cours d'exécution.

code

public static void main (String [] args) { AbstractApplicationContext CTX = new ClassPathXmlApplicationContext ("printemps-bean.xml"); ctx.registerShutdownHook();

Employee emp = new Employee("149518", "Mickey", "Mouse", "15 years", "tennis"); 

IEmployee empIntfc = (IEmployee)ctx.getBean("empService"); 
try { 
     empIntfc.createEmployee(emp); 
     empIntfc.createEmployeeDetails(emp); 

     //Below will throw RunTime Exception 
     empIntfc.getEmployee(2); 

    }catch (Exception e) { 
     e.printStackTrace(); 

    } finally { 
     ctx.close();  
    } 

}

EmployeeService.java

public class EmployeeService implements IEmployee { 

private DataSource dataSource; 
private JdbcTemplate jdbcTemplate; 

public void setDataSource(DataSource dataSource) { 
    this.dataSource = dataSource; 
    jdbcTemplate = new JdbcTemplate(this.dataSource); 
} 
public JdbcTemplate getJdbcTemplate() { 
    return jdbcTemplate; 
} 

@Override 
@Transactional 
public int createEmployee(Employee emp) {  

    String sql1 = "INSERT INTO TEST_T1(EMP_ID, EMP_FNAME, EMP_LNAME) values 
    (?,?,?)"; 
    return getJdbcTemplate().update(sql1, emp.getEmpId(), 
    emp.getEmpFirstName(), emp.getEmpLastName()); 
} 

@Override 
@Transactional 
public int createEmployeeDetails(Employee emp) { 

    String sql = "INSERT INTO TEST_T2(EMP_ID, EXP, SKILLS) values (?,?,?)";  
    return getJdbcTemplate().update(sql, emp.getEmpId(), emp.getExp(), 
    emp.getSkills()); 
} 

@Override 
@Transactional(readOnly = true, noRollbackFor=RuntimeException.class) 
public Employee getEmployee(int empId) { 
    throw new RuntimeException("Intentional runtime exception"); 
} 

}

printemps-bean.xml

<beans xmlns="http://www.springframework.org/schema/beans"> 

<context:annotation-config/> 
<tx:annotation-driven transaction-manager="transactionManager"/> 

<bean id="transactionManager" 
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
<property name="dataSource" ref="dataSource"/> 
</bean> 
<bean id="dataSource" 
    class="org.springframework.jdbc.datasource.DriverManagerDataSource" > 
    <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/> 
    <property name="url" value="jdbc:oracle:thin:@//xxxx:1521/xxxx"/> 
    <property name="username" value="user"/> 
    <property name="password" value="user"/> 
    </bean> 
    <bean id="empService" class="com.service.EmployeeService"> 
    <property name="dataSource" ref="dataSource"/> 
    </bean> 
    </beans> 
+0

Il existe déjà une solution acceptée ici - http://stackoverflow.com/questions/9649318/how-can-i-config-to-turn-off-autocommit-in-spring-jdbc – Rohith

+0

Votre méthode principale n'est pas transactionnel ... signifie: entrer 'createEmployee' crée une nouvelle transaction et la valide, 'createEmployeeDetails' crée une nouvelle transaction et la valide ... – Pras

+0

J'ai fait la méthode main() transactionnelle mais cela n'a pas fonctionné. A pris votre pointeur et enveloppé les appels à createEmployee, createEmployeeDetails et getEmployee dans une classe différente. Utilisé transactionnel dans la nouvelle méthode de classe et cela fonctionne maintenant. Merci pour votre aide. –

Répondre

0

Votre principale méthode est transactionnel non ... signifie: entrer 'createEmployee' crée un 'createEmployeeDetails' crée une nouvelle transaction et la valide.