spring JDBC事务使用经验
2013-11-04 15:26
330 查看
最近在使用spring的JDBC事务时出现了一个问题:在多线程环境中,主线程获取一个
DataSourceTransactionManager,开启事务,同时在子线程中也使用同一个事务管理器开启事务,但是当子线程中的事务发生回滚后,主线程的事务继续执行,没有同步回滚。因此我怀疑spring JDBC事务不支持跨线程,于是乎翻阅了spring中关于事务的代码,发现果然如此,其关键在于TransactionSynchronizationManager中,代码如下:
特别记录下来,防止以后忘记!!!!!遇到同样问题的童鞋也可以参考一下,共同进步!!
DataSourceTransactionManager,开启事务,同时在子线程中也使用同一个事务管理器开启事务,但是当子线程中的事务发生回滚后,主线程的事务继续执行,没有同步回滚。因此我怀疑spring JDBC事务不支持跨线程,于是乎翻阅了spring中关于事务的代码,发现果然如此,其关键在于TransactionSynchronizationManager中,代码如下:
package org.springframework.transaction.support; /** * Central helper that manages resources and transaction synchronizations per thread. * To be used by resource management code but not by typical application code. * * <p>Supports one resource per key without overwriting, that is, a resource needs * to be removed before a new one can be set for the same key. * Supports a list of transaction synchronizations if synchronization is active. * * <p>Resource management code should check for thread-bound resources, e.g. JDBC * Connections or Hibernate Sessions, via <code>getResource</code>. Such code is * normally not supposed to bind resources to threads, as this is the responsibility * of transaction managers. A further option is to lazily bind on first use if * transaction synchronization is active, for performing transactions that span * an arbitrary number of resources. * * <p>Transaction synchronization must be activated and deactivated by a transaction * manager via {@link #initSynchronization()} and {@link #clearSynchronization()}. * This is automatically supported by {@link AbstractPlatformTransactionManager}, * and thus by all standard Spring transaction managers, such as * {@link org.springframework.transaction.jta.JtaTransactionManager} and * {@link org.springframework.jdbc.datasource.DataSourceTransactionManager}. * * <p>Resource management code should only register synchronizations when this * manager is active, which can be checked via {@link #isSynchronizationActive}; * it should perform immediate resource cleanup else. If transaction synchronization * isn't active, there is either no current transaction, or the transaction manager * doesn't support transaction synchronization. * * <p>Synchronization is for example used to always return the same resources * within a JTA transaction, e.g. a JDBC Connection or a Hibernate Session for * any given DataSource or SessionFactory, respectively. * * @author Juergen Hoeller * @since 02.06.2003 * @see #isSynchronizationActive * @see #registerSynchronization * @see TransactionSynchronization * @see AbstractPlatformTransactionManager#setTransactionSynchronization * @see org.springframework.transaction.jta.JtaTransactionManager * @see org.springframework.jdbc.datasource.DataSourceTransactionManager * @see org.springframework.jdbc.datasource.DataSourceUtils#getConnection */ public abstract class TransactionSynchronizationManager { private static final Log logger = LogFactory.getLog(TransactionSynchronizationManager.class); //所有关于事务的资源变量都定义成了线程变量,所以jdbc事务不支持跨线程 //resources资源用来存储connection,key是DataSource(把连接与当前线程绑定,保证一个事务使用一个连接)。spring团队把带有状态的connection与当前线程绑定,设计的非常巧妙!! private static final ThreadLocal<Map<Object, Object>> resources = new NamedThreadLocal<Map<Object, Object>>("Transactional resources"); private static final ThreadLocal<Set<TransactionSynchronization>> synchronizations = new NamedThreadLocal<Set<TransactionSynchronization>>("Transaction synchronizations"); private static final ThreadLocal<String> currentTransactionName = new NamedThreadLocal<String>("Current transaction name"); private static final ThreadLocal<Boolean> currentTransactionReadOnly = new NamedThreadLocal<Boolean>("Current transaction read-only status"); private static final ThreadLocal<Integer> currentTransactionIsolationLevel = new NamedThreadLocal<Integer>("Current transaction isolation level"); private static final ThreadLocal<Boolean> actualTransactionActive = new NamedThreadLocal<Boolean>("Actual transaction active"); //------------------------------------------------------------------------- // Management of transaction-associated resource handles //------------------------------------------------------------------------- ....... }
特别记录下来,防止以后忘记!!!!!遇到同样问题的童鞋也可以参考一下,共同进步!!
相关文章推荐
- 【Spring】在Spring框架下使用注解配置JDBC事务
- 在spring中使用JDBC事务配置
- spring jdbc 事务配置----TransactionTemplate使用
- Spring JDBC使用、事务管理
- day03-spring与数据库操作的框架解析即dataSource的获取(JDBC)、使用spring中已经有的事务进行JDBC操作
- 【Spring 事务管理系列之一】Spring使用JDBC的事务管理例子
- Spring JDBC-使用注解配置声明式事务
- 【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】
- Spring-jdbc:事务管理器的使用
- Spring 事务操作(银行转账案例),使用spring 对jdbc的支持完成对数据库的操作
- Spring - Jdbc的使用 和 Spring进行事务控制
- 使用注解方式配置spring中的jdbc事务
- Spring学习心得(22)-- spring声明式事务处理(使用jdbc操作数据库)
- hibernate,spring管理事务中(transaction,JDBC connection,Hibernate Session的使用)
- Spring 使用注解方式进行事务管理
- spring事务 Propagation.REQUIRES_NEW、Propagation.NESTED、Propagation.REQUIRED使用时候发现的
- Spring 事务的配置和使用详解(包括手动对事务的控制部分)
- 使用Spring的JDBC实现
- 使用Spring配置文件实现事务管理
- 使用Spring的SimpleJdbcTemplate类实现jdbc为基础的DAO层