标签: spring-transactions

使用 REQUIRES_NEW 对事务方法进行单元测试并始终强制回滚

我想测试一种通过在循环中调用 DAO 将数据插入表的服务方法。服务方法被注释为

@Transactional(propagation = Propagation.REQUIRES_NEW)
Run Code Online (Sandbox Code Playgroud)

单元测试调用服务方法并用

@Transactional
Run Code Online (Sandbox Code Playgroud)

现在我想告诉事务,它始终应该在最后进行回滚。我不想在测试运行后手动清理数据库。

@Rollback 和 EntityManager.getTransaction().setRollbackOnly() 不起作用。我认为原因是注释和 setRollbackOnly() 仅应用于由测试方法创建的事务,而不应用于由服务方法创建的事务。

有谁知道如何解决这个问题?

junit spring jpa spring-transactions

6
推荐指数
1
解决办法
3191
查看次数

Spring @Transactional 是否使用任何 Hibernate 缓存?

@Transactional
public MyEntity getEntity(long id) {
    return dao.findOne(id);

    //or select and update as well
}
Run Code Online (Sandbox Code Playgroud)

每次调用事务方法时:我会从休眠中获取任何缓存的实体吗(第一次除外)?或者我总是会从数据库中获取新的实体?

这很重要,因为我将有两个独立的应用程序共享同一个数据库,并且我想确保 hibernate 不会返回任何缓存的实体,而另一个应用程序可能已经在后台更新了数据库中的同一个实体。

java spring hibernate transactions spring-transactions

6
推荐指数
1
解决办法
3741
查看次数

Spring @Transactional 超时未按预期工作

我有一个 JDBC 批量更新操作可能需要很长时间,因此我使用事务超时来处理这个。

@Override
@Transactional(propagation=Propagation.REQUIRES_NEW,timeout=10)
public void saveAllUsingBatch(List<KillPrintModel> list){
    PreparedStatmentMapper ps=  new HibernateDao.PreparedStatmentMapper<KillPrintModel>() {

        @Override
        public void prepareStatement(PreparedStatement ps, KillPrintModel t)
                throws SQLException {
            ps.setString(1, t.getOffice());
            ps.setString(2, t.getAccount());
            ps.setDate(3, new java.sql.Date(t.getUpdatedOn().getTime()));
        }
    };
    String sql = String.format("INSERT INTO dbo.%s (%s,%s,%s) VALUES (?,?,?)",KillPrintModel.TABLE_NAME,KillPrintModel.FIELD_Office,KillPrintModel.FIELD_Account,KillPrintModel.FIELD_UpdatedOn);
    this.jdbcBatchOperation(list, sql, ps);
}
Run Code Online (Sandbox Code Playgroud)

即使我的事务时间超过 10 秒,此方法也会持续一分钟以上(并成功返回)。当超时为 0 时它工作正常。


是不是因为我的线程一旦开始执行就一直处于运行状态?

java spring-transactions

6
推荐指数
1
解决办法
4019
查看次数

Spring Jedis连接没有返回池中

我的应用程序是由Spring休息控制器使用redis调用服务.我使用的是spring boot starter redis 1.2.5,我在beans.xml文件中定义了一个模板:

<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
    p:host-name="${spring.redis.host}"
    p:use-pool="true" 
    p:port="${spring.redis.port}"
/>

<bean id="redisTemplateForTransaction" class="org.springframework.data.redis.core.RedisTemplate"
    p:connection-factory-ref="jedisConnectionFactory"
    p:keySerializer-ref="stringRedisSerializer"
    p:valueSerializer-ref="jsonRedisSerializerForTransaction"
    p:enableTransactionSupport="true">
    <qualifier value="redisTemplateForTransaction" />
</bean>
Run Code Online (Sandbox Code Playgroud)

当我启动超过8个查询时,我的应用程序阻止.我知道我已达到池中的默认连接数.

为什么在请求处理结束时没有自动返回连接?

如何在事务模式下工作,以便任何传入的请求将获得其redis连接并在处理结束时返回它?

java spring spring-mvc redis spring-transactions

6
推荐指数
1
解决办法
946
查看次数

当@ActiveProfiles("test") 时,如何忽略特定方法的 spring @Transactional 注释

@Transactional在集成测试期间,我需要忽略以下注释。

@Service
public class MyClass {

    @Transactional(propagation = Propagation.NEVER)
    public void doSomething() {
        // do something that once in production can not be inside a transaction (reasons are omitted)
    }

}
Run Code Online (Sandbox Code Playgroud)

问题是我所有的测试都是在默认回滚的事务中执行的。@Transactional(propagation = Propagation.NEVER)当此方法在测试 ( @ActiveProfiles("test"))范围内运行时,我怎么能忽略它的注释,允许它在事务内执行?

java spring spring-transactions

6
推荐指数
1
解决办法
2199
查看次数

@Transactional 注释方法是否等待 Spring 中的成功提交?

@Transactional在Spring中使用注解方法时,注解方法的返回是否与底层数据库事务的成功提交同步?

(这是假设事务在返回后实际上会提交,这可能不是这种情况,具体取决于所选的传播方法。)

如果等待提交不是默认行为,有没有办法通过配置或其他方式启用它?

我的问题的动机是我想实现一个可靠的“存储和转发”类型的端点,它只在调用的影响被提交到稳定存储后才向客户端返回响应。这可能@Transactional吗?

java spring spring-transactions

6
推荐指数
1
解决办法
8954
查看次数

双重嵌套事务的回滚绕过保存点

这并不完全像标题所说的那样,但接近。考虑这些 Spring bean:

@Bean
class BeanA {

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = EvilException.class)
    public void methodA() {
        /* ... some actions */
        if (condition) {
            throw new EvilException();
        }
    }
}

@Bean
class BeanB {
    @Autowired private BeanA beanA;
    final int MAX_TRIES = 3;

    @Transactional(propagation = Propagation.NESTED)
    public void methodB() {
        // prepare to call Bean A
        try {
            beanA.methodA();
            /* maybe do some more things */
        }
        catch (EvilException e) {
           /* recover from evil */
        }
    }
} …
Run Code Online (Sandbox Code Playgroud)

java spring jdbc spring-transactions

6
推荐指数
1
解决办法
190
查看次数

事务回滚在 Spring Data MongoDB 中不起作用

我正在使用Spring Data MongoDB(2.2.5)MongoDB 4.2.5 社区版本测试事务回滚功能。正如Spring Data官方文档中提到的,我在配置类中配置了MongoTransactionManager,并在后端创建了一个包含3个成员的副本集。

此外,还使用了 mongo 数据库事务存储库。使用@Transactional注释了我的Dao方法。即使我已经在方法中实现了事务范围,我的数据仍然保存在集合中(人员以及地址),并且在应用程序中的运行时异常上数据库层没有发生回滚。我已经提供了我的应用程序所需的源代码和跟踪。请帮助解决真实问题,如果我遗漏了任何内容,请告诉我。

@Slf4j
@Configuration
@EnableMongoRepositories
@EnableTransactionManagement(proxyTargetClass=true)
class ApplicationConfig  extends AbstractMongoClientConfiguration {

    @Bean
    MongoTransactionManager transactionManager(MongoDbFactory dbFactory) {  
        log.info("Creating dbFactory {}", dbFactory);
        MongoTransactionManager manager=new MongoTransactionManager(dbFactory);
        log.info("Creating manager {}",manager);
        return manager;
    }

    @Override
    public MongoClient mongoClient() {

        return MongoClients.create("mongodb://localhost:27020,localhost:27021,localhost:27022/?replicaSet=rs0");

    }

    @Override
    protected String getDatabaseName() {
        return "testDB";
    }

    public @Bean MongoTemplate mongoTemplate() {
          return new MongoTemplate(mongoClient(), "testDB");
      }

}

@Slf4j
@Service("TestDao")
public class TestDaoImpl implements TestDao{

    @Autowired
    PersonRepository repository;

    @Autowired
    MongoOperations ops;

    @Autowired …
Run Code Online (Sandbox Code Playgroud)

spring-transactions spring-data-mongodb

6
推荐指数
0
解决办法
1632
查看次数

为什么@Transactional 隔离级别在使用 Spring Data JPA 更新实体时不起作用?

对于这个基于spring-boot-starter-data-jpa依赖和H2内存数据库的实验项目,我定义了一个User具有两个字段(idfirstName)的实体,并UsersRepository通过扩展CrudRepository接口声明了一个。

现在,考虑一个简单的控制器,它提供两个端点:/print-user读取同一用户两次,间隔打印其名字,并/update-user用于在两次读取之间更改用户的名字。请注意,我特意设置了Isolation.READ_COMMITTEDlevel 并期望在第一次事务过程中,通过相同 id 检索两次的用户将具有不同的名称。但是相反,第一笔交易打印出两次相同的值。为了更清楚,这是完整的操作序列:

  1. 最初,jeremy的名字设置为Jeremy
  2. 然后我调用/print-userwhich 打印出来Jeremy并进入睡眠状态。
  3. 接下来,我/update-user从另一个会话调用,它将jeremy的名字更改为Bob.
  4. 最后,当第一个事务在睡眠后被唤醒并重新读取jeremy用户时,Jeremy即使名字已经更改为他的名字,它也会再次打印出来Bob(如果我们打开数据库控制台,它现在确实存储为Bob,不是Jeremy)。

似乎在这里设置隔离级别没有任何影响,我很好奇为什么会这样。

@RestController
@RequestMapping
public class UsersController {

    private final UsersRepository usersRepository;

    @Autowired
    public UsersController(UsersRepository usersRepository) {
        this.usersRepository = usersRepository;
    }

    @GetMapping("/print-user")
    @ResponseStatus(HttpStatus.OK)
    @Transactional (isolation = Isolation.READ_COMMITTED) …
Run Code Online (Sandbox Code Playgroud)

java spring spring-transactions spring-data-jpa spring-boot

6
推荐指数
1
解决办法
950
查看次数

Kotlin 的 Arrow &lt;Exception, X&gt; 和交易

我正在尝试使用 Kotlin 的 Arrow 库Either对象来处理项目中的异常。

到目前为止,我的经验还不错,但我正在努力寻找一种方法来处理事务Either,特别是回滚。在 Spring 中抛出 aRuntimeException是导致事务回滚的可靠方法。但是,通过使用Either不会引发异常,因此不会触发回滚。

您可以将此视为一个多方面的问题:

  1. 是否Either适合真实Exception处理?不是替代控制流,我的意思是程序流需要停止的真正错误情况。
  2. 如果是这样,您如何通过它们实现回滚?
  3. 如果问题 2. 的答案是以transactionManager编程方式使用- 你能避免这种情况吗?
  4. 我把这个挤进去,你如何避免嵌套Either

spring spring-transactions spring-data-jpa kotlin arrow-kt

6
推荐指数
1
解决办法
343
查看次数