如果你已经排除了以下问题:
 
 https://blog.csdn.net/qq_20597727/article/details/84900994
 
 或是数据库本身不支持, 如MySQL的Myisam.
 
 
不防看看是不是由多数据源引起的:
 
 
多数据源我们一般这样配置:
  
@Configuration
    @EnableDataSource("A")
    @EnableJpaRepositories(
        repositoryFactoryBeanClass = CustomRepositoryFactoryBean.class,
        entityManagerFactoryRef = "defaultEntityManagerFactory",
        basePackages = {"com.A.dao"},
        transactionManagerRef = "defaultTransactionManager"
    )
    @ConditionalOnProperty(
        prefix = "XXX.datasource.default",
        name = {"driverClassName", "url", "username", "password"}
    )
    protected static class DataSourceDefaultConfiguration {
        private static final Logger log = LoggerFactory.getLogger(DataSourceConfiguration.DataSourceDefaultConfiguration.class);
        protected DataSourceDefaultConfiguration() {
        }
    }
@Configuration
    @EnableDataSource("B")
    @EnableJpaRepositories(
        repositoryFactoryBeanClass = CustomRepositoryFactoryBean.class,
        entityManagerFactoryRef = "myGblEntityManagerFactory",
        basePackages = {"com.B.dao"},
        transactionManagerRef = "myGblTransactionManager"
    )
    @ConditionalOnProperty(
        prefix = "XXX.datasource.myGbl",
        name = {"driverClassName", "url", "username", "password"}
    )
    protected static class DataSourceMyGblConfiguration {
        private static final Logger log = LoggerFactory.getLogger(DataSourceConfiguration.DataSourceMyGblConfiguration.class);
        protected DataSourceMyGblConfiguration() {
        }
    }
 
 这样, 其中一个数据源就是默认的数据源, 如A. 如果使用@Transaction注解开启事务, 默认使用默认数据源A来进行开启, 提交, 回滚 事务, 这个时候如果@Transaction方法里面是对com.B.dao进行的操作, 那么其实事务也是作用在A数据源上, 就会产生事务不生效的假象.
 
这时需指定事务对象来声明事务: @Transactional(value = "myGblTransactionManager"), 这时事务会作用在com.B.dao的操作上.
 
 
关于事务是否生效, 可以从这里入手检查:
  
org.springframework.orm.jpa.JpaTransactionManager
 
  
@Override
	protected void doBegin(Object transaction, TransactionDefinition definition) {
		JpaTransactionObject txObject = (JpaTransactionObject) transaction;
		if (txObject.hasConnectionHolder() && !txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
			throw new IllegalTransactionStateException(
					"Pre-bound JDBC Connection found! JpaTransactionManager does not support " +
					"running within DataSourceTransactionManager if told to manage the DataSource itself. " +
					"It is recommended to use a single JpaTransactionManager for all transactions " +
					"on a single DataSource, no matter whether JPA or JDBC access.");
		}
		try {
			if (!txObject.hasEntityManagerHolder() ||
					txObject.getEntityManagerHolder().isSynchronizedWithTransaction()) {
 如果是非JpaTransactionManager, 可以从其接口入手PlatformTransactionManager
          
            
          
             
已有   0 人发表留言,猛击->>  这里<<-参与讨论
          
             
ITeye推荐