1

我正在用 Spring Transaction 做一些测试,这是我的配置:

@Repository
public class ClienteDaoJdbc implements ClienteDao {

private static final String SQL_INSERT = "INSERT INTO clientes (CodigoCliente,Nombres) "
                    + "VALUES (:codigo_cliente,:nombres)";

@Autowired
private NamedParameterJdbcTemplate jdbcTemplate;

public void insertBatch(List<Cliente> clientes) {
    Map<String, Object>[] batchValues = new HashMap[clientes.size()];
    for (int i = 0; i < batchValues.length; i++) {
        Map<String, Object> parametros = new HashMap<String, Object>();
        parametros.put("codigo_cliente", clientes.get(i).getCodigoCliente());
        parametros.put("nombres", clientes.get(i).getNombres());
        batchValues[i] = parametros;
    }
    this.jdbcTemplate.batchUpdate(SQL_INSERT, batchValues);
    }
}

服务

@Service
@Transactional(readOnly=true)
public class ClienteServiceImpl implements ClienteService {

    @Autowired
    private ClienteDao clienteDao;

    @Transactional(readOnly=false,propagation=Propagation.REQUIRES_NEW)
    public void register(List<Cliente> clientes) {
        this.clienteDao.insertBatch(clientes);
    }

}

弹簧配置

<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/test"/>
        <property name="username" value="root"/>
        <property name="password" value=""/>
        <property name="defaultAutoCommit" value="false"/>
    </bean>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
        <constructor-arg ref="dataSource"/>
    </bean>

    <context:component-scan base-package="com.varas"/>

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <context:annotation-config/>

    <tx:annotation-driven/>

当我在独立的应用程序事务中使用此代码时,它完美运行,为此我使用一些代码来测试此应用程序,我得到:

DEBUG: org.springframework.jdbc.datasource.DataSourceTransactionManager - Rolling back JDBC transaction on Connection [ProxyConnection[PooledConnection[com.mysql.jdbc.JDBC4Connection@1a10a9a1]]]
DEBUG: org.springframework.jdbc.datasource.DataSourceTransactionManager - Releasing JDBC Connection [ProxyConnection[PooledConnection[com.mysql.jdbc.JDBC4Connection@1a10a9a1]]] after transaction
DEBUG: org.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
Exception in thread "main" org.springframework.dao.DuplicateKeyException: PreparedStatementCallback; SQL [INSERT INTO clientes (CodigoCliente,Nombres) VALUES (?,?)]; Duplicate entry '0000000007' for key 'PRIMARY'; nested exception is java.sql.BatchUpdateException: Duplicate entry '0000000007' for key 'PRIMARY'

回滚过程有效,但是当我在 Spring MVC 项目中使用相同的代码时,spring 事务显然不起作用,并且回滚过程永远不会发生

DEBUG: org.springframework.jdbc.core.JdbcTemplate - Executing SQL batch update [INSERT INTO clientes (CodigoCliente,Nombres) VALUES (?,?)]
DEBUG: org.springframework.jdbc.core.JdbcTemplate - Executing prepared SQL statement [INSERT INTO clientes (CodigoCliente,Nombres) VALUES (?,?)]
DEBUG: org.springframework.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource
DEBUG: org.springframework.jdbc.support.JdbcUtils - JDBC driver supports batch updates
DEBUG: org.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]
INFO : org.springframework.jdbc.support.SQLErrorCodesFactory - SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase]
DEBUG: org.springframework.jdbc.support.SQLErrorCodesFactory - Looking up default SQLErrorCodes for DataSource [org.apache.tomcat.jdbc.pool.DataSource@3291ea21{ConnectionPool[defaultAutoCommit=false; defaultReadOnly=null; defaultTransactionIsolation=-1; defaultCatalog=null; driverClassName=com.mysql.jdbc.Driver; maxActive=100; maxIdle=100; minIdle=10; initialSize=10; maxWait=30000; testOnBorrow=false; testOnReturn=false; timeBetweenEvictionRunsMillis=5000; numTestsPerEvictionRun=0; minEvictableIdleTimeMillis=60000; testWhileIdle=false; testOnConnect=false; password=********; url=jdbc:mysql://localhost:3306/test; username=root; validationQuery=null; validatorClassName=null; validationInterval=30000; accessToUnderlyingConnectionAllowed=true; removeAbandoned=false; removeAbandonedTimeout=60; logAbandoned=false; connectionProperties=null; initSQL=null; jdbcInterceptors=null; jmxEnabled=true; fairQueue=true; useEquals=true; abandonWhenPercentageFull=0; maxAge=0; useLock=false; dataSource=null; dataSourceJNDI=null; suspectTimeout=0; alternateUsernameAllowed=false; commitOnReturn=false; rollbackOnReturn=false; useDisposableConnectionFacade=true; logValidationErrors=false; propagateInterruptState=false; }]
DEBUG: org.springframework.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource
DEBUG: org.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
DEBUG: org.springframework.jdbc.support.SQLErrorCodesFactory - Database product name cached for DataSource [org.apache.tomcat.jdbc.pool.DataSource@3291ea21]: name is 'MySQL'
DEBUG: org.springframework.jdbc.support.SQLErrorCodesFactory - SQL error codes for 'MySQL' found
DEBUG: org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator - Translating SQLException with SQL state '23000', error code '1062', message [Duplicate entry '0000000007' for key 'PRIMARY']; SQL was [INSERT INTO clientes (CodigoCliente,Nombres) VALUES (?,?)] for task [PreparedStatementCallback]
jul 23, 2013 9:15:57 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: El Servlet.service() para el servlet [appServlet] en el contexto con ruta [/comercial] lanz? la excepci?n [Request processing failed; nested exception is org.springframework.dao.DuplicateKeyException: PreparedStatementCallback; SQL [INSERT INTO clientes (CodigoCliente,Nombres) VALUES (?,?)]; Duplicate entry '0000000007' for key 'PRIMARY'; nested exception is java.sql.BatchUpdateException: Duplicate entry '0000000007' for key 'PRIMARY'] con causa ra?z
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '0000000007' for key 'PRIMARY'

我不知道为什么 Spring Transaction 在这种情况下不起作用,在 We App 环境中?提前感谢您的回复。

4

0 回答 0