mysql事务回滚了 但数据还是插入数据库

挨踢职业人 发布于 2012/05/15 16:06
阅读 6K+
收藏 1

调用service insertProduct :

public class TestTranscationServerImpl implements TestTranscationServer {
	
	private Product1 product1;
	public void setProduct1(Product1 product1) {
		this.product1 = product1;
	}

	public void setProduct2(Product2 product2) {
		this.product2 = product2;
	}

	private Product2 product2;

	public void insertProduct(String productId, String productName) throws Exception {
		this.product1.insertProduct("product1--"+productId, productName);
		this.product2.insertProduct("product2--"+productId, productName);
		throw new Exception("xxxxx");
//		throw new Exception("xxxx");
	}

log:

 

================================insert product startnull
DEBUG(AbstractBeanFactory.java:244)DefaultListableBeanFactory:244 - Returning cached instance of singleton bean 'testTranscation'
DEBUG(AbstractPlatformTransactionManager.java:365)JtaTransactionManager:365 - Creating new transaction with name [secoo.server.impl.TestTranscationServerImpl.insertProduct]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly,-Throwable
 INFO(Slf4jConsole.java:110)atomikos:110 - THREADS: using JDK thread pooling...
 INFO(Slf4jConsole.java:110)atomikos:110 - createCompositeTransaction ( 300000 ): created new ROOT transaction with id com.atomikos.spring.jdbc.tm0000100018
DEBUG(DataSourceUtils.java:110)DataSourceUtils:110 - Fetching JDBC Connection from DataSource
DEBUG(DataSourceUtils.java:114)DataSourceUtils:114 - Registering transaction synchronization for JDBC Connection
DEBUG(Slf4jImpl.java:28)Connection:28 - ooo Connection Opened
DEBUG(Slf4jImpl.java:28)PreparedStatement:28 - ==>  Executing: insert into product1(productId,productName) values(?,?)
DEBUG(Slf4jImpl.java:28)PreparedStatement:28 - ==> Parameters: product1--277(String), ��277����Ʒ(String)
DEBUG(DataSourceUtils.java:110)DataSourceUtils:110 - Fetching JDBC Connection from DataSource
DEBUG(DataSourceUtils.java:114)DataSourceUtils:114 - Registering transaction synchronization for JDBC Connection
DEBUG(Slf4jImpl.java:28)Connection:28 - ooo Connection Opened
DEBUG(Slf4jImpl.java:28)PreparedStatement:28 - ==>  Executing: insert into product1(productId,productName) values(?,?)
DEBUG(Slf4jImpl.java:28)PreparedStatement:28 - ==> Parameters: product2--277(String), ��277����Ʒ(String)
DEBUG(AbstractPlatformTransactionManager.java:843)JtaTransactionManager:843 - Initiating transaction rollback
 INFO(Slf4jConsole.java:110)atomikos:110 - rollback() done of transaction com.atomikos.spring.jdbc.tm0000100018
DEBUG(DataSourceUtils.java:332)DataSourceUtils:332 - Returning JDBC Connection to DataSource
DEBUG(DataSourceUtils.java:332)DataSourceUtils:332 - Returning JDBC Connection to DataSource
java.lang.Exception: xxxxx
 at secoo.server.impl.TestTranscationServerImpl.insertProduct(TestTranscationServerImpl.java:23)
 at secoo.server.impl.TestTranscationServerImpl$$FastClassByCGLIB$$f42aceab.invoke(<generated>)

手动抛出的异常,但数据插入进去了

spring 配置

 

<jee:jndi-lookup id="dataSource1" jndi-name="jdbc/t1"/>
	<jee:jndi-lookup id="dataSource2" jndi-name="jdbc/t2"/>
	
	<bean class="secoo.test.SpringContextUtil"></bean>
	
	  <!--  读取数据库连接配置文件 -->
     <bean id="propertyConfig"
         class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                 <value>classpath:jdbc.properties</value>
             </list>
         </property>
     </bean>
	
	<!-- 第一个数据库
    <bean id="dataSource1" class="com.atomikos.jdbc.AtomikosDataSourceBean"  
        init-method="init" destroy-method="close">
        <property name="uniqueResourceName" value="mysql/product1" />
        <property name="xaDataSourceClassName"
            value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />  
        <property name="xaProperties">
        	<props>
                <prop key="user">${jdbc.username.a}</prop>
                <prop key="password">${jdbc.password.a}</prop>
                <prop key="URL">${jdbc.url.a}</prop>
            </props>
        </property>
        <property name="testQuery">  
            <value>SELECT 1</value>  
        </property>
    </bean>    -->
    <!-- 第二个数据库 
    <bean id="dataSource2" class="com.atomikos.jdbc.AtomikosDataSourceBean"  
        init-method="init" destroy-method="close">
        <property name="uniqueResourceName" value="mysql/product2" />
        <property name="xaDataSourceClassName"
            value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />  
        <property name="xaProperties">
        	<props>
                <prop key="user">${jdbc.username.b}</prop>
                <prop key="password">${jdbc.password.b}</prop>
                <prop key="URL">${jdbc.url.b}</prop>
            </props>
        </property>
        <property name="testQuery">  
            <value>SELECT 1</value>  
        </property>
    </bean> 
	  -->
	 
	<!-- SessionFactory -->
	<bean id="sqlSessionFactory1" class="org.mybatis.spring.SqlSessionFactoryBean">  
	    <property name="dataSource" ref="dataSource1" /> 
	</bean> 
	
	<bean id="sqlSessionFactory2" class="org.mybatis.spring.SqlSessionFactoryBean">  
	    <property name="dataSource" ref="dataSource2" /> 
	</bean>  
  
    <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" 
    	init-method="init" destroy-method="close">
        <description>UserTransactionManager</description>
        <property name="forceShutdown">
            <value>true</value>
        </property>
    </bean>
    
    
    <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">  
        <property name="transactionTimeout" value="300" />  
    </bean> 
     
    <bean id="springTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">  
        <property name="transactionManager" ref="atomikosTransactionManager"/> 
        <property name="userTransaction" ref="atomikosUserTransaction" /> 
        <property name="allowCustomIsolationLevels" value="true"/>
        <property name="globalRollbackOnParticipationFailure" value="false" /> 
    </bean> 
    
    <aop:aspectj-autoproxy /> 
    
    <aop:config  proxy-target-class="true">  
        <aop:advisor pointcut="execution(* com.server.impl.*.*(..))" 
            advice-ref="txAdvice" /> 
        </aop:config> 
  
    <tx:advice id="txAdvice" transaction-manager="springTransactionManager">  
        <tx:attributes> 
        	<tx:method name="insert*" propagation="REQUIRED" read-only="true" rollback-for="Throwable"/>
			<tx:method name="delete*" propagation="REQUIRED" read-only="true" rollback-for="Throwable"/>
			<tx:method name="update*" propagation="REQUIRED" read-only="true" rollback-for="Throwable"/>
            <tx:method name="*" propagation="SUPPORTS" rollback-for="Exception"  />  
        </tx:attributes>  
    </tx:advice>

不用jndi数据源就可以成功回滚 

tomcat content:

 

<Resource name="jdbc/t1"
      auth="Container"
      type="javax.sql.XADataSource"
      factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
      testWhileIdle="true"
      testOnBorrow="true"
      testOnReturn="false"
      validationQuery="SELECT 1"
      validationInterval="3000"
      timeBetweenEvictionRunsMillis="3000"
      maxActive="10"
      minIdle="5"
	  maxIdle="10"
      maxWait="1000"
      initialSize="5"
	  commitOnReturn="false"
      removeAbandonedTimeout="60"
      removeAbandoned="true"
      logAbandoned="true"
      minEvictableIdleTimeMillis="3000"
      jmxEnabled="true"
      jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"
	  driverClassName="com.mysql.jdbc.Driver"
      username="root"
      password="root"
      url="jdbc:mysql://127.0.0.1:3306/t1?useUnicode=true&amp;characterEncoding=utf8"/>
	  
	  <Resource name="jdbc/t2"
      auth="Container"
      type="javax.sql.XADataSource"
      factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
      testWhileIdle="true"
      testOnBorrow="true"
      testOnReturn="false"
      validationQuery="SELECT 1"
      validationInterval="3000"
      timeBetweenEvictionRunsMillis="3000"
      maxActive="10"
      minIdle="5"
	  maxIdle="10"
      maxWait="1000"
      initialSize="5"
      removeAbandonedTimeout="60"
      removeAbandoned="true"
      logAbandoned="true"
	  commitOnReturn="false"
      minEvictableIdleTimeMillis="3000"
      jmxEnabled="true"
      jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"
	  driverClassName="com.mysql.jdbc.Driver"
      username="root"
      password="root"
      url="jdbc:mysql://192.168.1.224:3306/t2?useUnicode=true&amp;characterEncoding=utf8"/>

以下是问题补充:

@挨踢职业人:用tomcat7 的Tomcat JDBC Connection Pool JNDI 方式就不好使,改成普通数据源com.atomikos.jdbc.AtomikosDataSourceBean 能回滚数据 (2012/05/15 17:28)
加载中
0
挨踢职业人
挨踢职业人
哪位帮忙大神看看
0
挨踢职业人
挨踢职业人

引用来自“wad12302”的答案

spring 的你使用 运行时异常。

还有你看下 

<aop:config  proxy-target-class="true"
84         <aop:advisor pointcut="execution(* com.server.impl.*.*(..))"
85             advice-ref="txAdvice" />
86

        </aop:config>

结构是否拦截得当com.server.impl.*.*(..)

好像有的是拦截接口,而不是实现类

连接到了  这个地方代码 贴 错了

 com.server.impl ==> secoo.server.impl

问题是我用 com.atomikos.jdbc.AtomikosDataSourceBean  这个数据源就好使 ,

用tomcat7的 Tomcat JDBC Connection Pool 的就不好使

0
挨踢职业人
挨踢职业人

引用来自“wad12302”的答案

跟连接没有关系。

如果你使用spring没有回滚。是否是运行时异常RuntimeException,而不是Exception,还有aop切入点是否正确

我就只是把

<jee:jndi-lookup id="dataSource1" jndi-name="jdbc/t1"/>

<jee:jndi-lookup id="dataSource2" jndi-name="jdbc/t2"/>

注释掉,改用atomikos 的数据源 ,其他都不变 就能成功回滚 

0
wad12302
wad12302

我搞错了!

 

0
wad12302
wad12302
使用jndi 时候好像jta管理还需要配合其他管理工具管理吧,原来我使用jotm ,但是jotm好久没维护了,使用过程中有好多问题。
0
回忆书签
回忆书签

mysql数据库中root用户的操作应该是默认自动提交的。

试试换一个普通用户并赋予响应的权限。

0
傅小黑
傅小黑
会不会是myisam引擎啊。。
0
挨踢职业人
挨踢职业人

innodb ,不然怎么另外一种可以回滚呢

0
挨踢职业人
挨踢职业人

引用来自“傅小黑”的答案

会不会是myisam引擎啊。。

innodb引擎

返回顶部
顶部