为什么@Transactional注释不起作用?

时间:2015-04-18 12:07:43

标签: java spring transactions

此代码与某些数据库操作有关:

@Component("trans")
 public class CustomerTransactionImp extends JdbcDaoSupport{

    public static final Logger logger = Logger.getLogger(CustomerTransactionImp.class.getName());

    @Autowired
    public CustomerTransactionImp(DataSource dataSource) {
        setDataSource(dataSource);
    }

    @Transactional
    public void deleteCustomerByName(String name){
        String sql = "DELETE FROM CUSTOMER WHERE firstName = ?";

        deleteCustomerByID((long) 100);
        displayAllCustomer();
        logger.info("Deleted customer named: "+ name);
        getJdbcTemplate().update(sql,name);
    }

    public void deleteCustomerByID(Long ID) {
        String sql = "DELETE FROM CUSTOMER WHERE id = ?";

        logger.info("Deleted customer named: "+ ID);
        getJdbcTemplate().update(sql, ID);
    }

    public List getAllCustomer(){
        String sql = "Select * FROM customer";

        return getJdbcTemplate().queryForList(sql);
    }

    public void displayAllCustomer() {
        for (Object o : getAllCustomer()) {
            System.out.println(o);
        }
    }
}

这是我的 Spring 配置文件:

    <context:annotation-config></context:annotation-config>
    <context:component-scan base-package="database.transactionmanagement"/>

    <jdbc:embedded-database id="dataSource">
        <jdbc:script location="sqlfiles/schema.sql"/>
        <jdbc:script location="sqlfiles/data.sql"/>
    </jdbc:embedded-database>

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

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <constructor-arg name="dataSource" ref="dataSource"/>
    </bean>
</beans>

我的测试班:

 @Test
public void trans_management_test() {
    ApplicationContext context = new ClassPathXmlApplicationContext("databaseconf/transaction-conf.xml");

    CustomerTransactionImp customerTransactionImp = context.getBean("trans", CustomerTransactionImp.class);

    customerTransactionImp.deleteCustomerByName("Omer");
    customerTransactionImp.displayAllCustomer();
}

所以基本代码,在我使用@Transactional annaotation的代码中,我创建了一个错误的SQL查询,该表不是我的db - :

 String sql = "DELETE FROM CUSTOMERWrong WHERE firstName = ?";

我的意思是,在deleteCustomerByName方法中,这里是deleteCustomerByID方法,此方法正常工作并提交。

根据事务,deleteCustomerByID方法不得提交,或者我对@Transactional注释的理解是错误的。 deleteCustomerByName方法下的SQL查询错误,而deleteCustomerByID下的SQL查询没问题,所有这些查询都不能提交???

1 个答案:

答案 0 :(得分:0)

我解决了我的问题,@ Transactal用于任何服务类(Customer,Manager),也使用实时数据库,我使用的是在RAM上运行的数据库。我的新代码如下:

@Test
    public void trans_management_test() {
        ApplicationContext context = new ClassPathXmlApplicationContext("databaseconf/transaction-conf.xml");

        CustomerManager customerTransactionImp = context.getBean("manager", CustomerManager.class);
        customerTransactionImp.operation("Administration", 110);
    }

@Component("trans")
public class CustomerTransactionImp extends JdbcDaoSupport{

    public static final Logger logger = Logger.getLogger(CustomerTransactionImp.class.getName());

    @Autowired
    public CustomerTransactionImp(DataSource dataSource) {
        setDataSource(dataSource);
    }

    @Transactional
    public void deleteCustomerByName(String name){
        String sql = "DELETE FROM departments WHERE department_name = ?";

        logger.info("Deleted customer named: "+ name);
        getJdbcTemplate().update(sql,name);
    }

    @Transactional
    public void deleteCustomerByID(Long ID) {
        String sql = "DELETE FROM departments WHERE department_id = ?";

        logger.info("Deleted customer named: "+ ID);
        getJdbcTemplate().update(sql, ID);
    }

@Component("manager")
public class CustomerManager {

    @Autowired
    CustomerTransactionImp transactionImp;

    @Transactional
    public void operation(String name , long ID){
        transactionImp.deleteCustomerByID(ID);
        transactionImp.deleteCustomerByName(name);
    }

    public CustomerTransactionImp getTransactionImp() {
        return transactionImp;
    }

 <context:annotation-config></context:annotation-config>
    <context:component-scan base-package="database.transactionmanagement"/>

    <bean id="datasource2" class="org.apache.tomcat.dbcp.dbcp2.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost/hr"/>
        <property name="username" value="root"/>
        <property name="password" value=""/>
    </bean>

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

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <constructor-arg name="dataSource" ref="datasource2"/>
    </bean>