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>
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
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
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. –