我正在使用Spring Transaction进行一些测试,这是我的配置:
DAO
@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'
我不知道为什么在这种情况下,在We App环境中,Spring Transaction不起作用? 提前感谢您的回复。