标签: 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中如何处理并发访问的事务

我有一种方法的服务:

    @Service
    public class DefaultTestService implements TestService {
        private static final Logger LOGGER = Logger.getLogger(DefaultTestService.class);
        @Autowired
        private TestRepository testRepository;

        @Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE)
        @Override
        public void incrementAndGet(Long testModelId) {
            LOGGER.debug("Transaction is active: " + TransactionSynchronizationManager.isActualTransactionActive());
            final TestModel tm = testRepository.findOne(testModelId);
            if (tm != null) {
                LOGGER.debug("Updated " + testModelId + " from value: " + tm.getValue());
                tm.setValue(tm.getValue() + 1);
                testRepository.save(tm);
            } else {
                LOGGER.debug("Saved with id: " + testModelId);
                final TestModel ntm = new TestModel();
                ntm.setId(testModelId);
                testRepository.save(ntm);
            } …
Run Code Online (Sandbox Code Playgroud)

java spring spring-transactions spring-data

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

当@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禁用单个类方法的事务

在我的Spring应用程序中,我有一个带有org.springframework.transaction.annotation.Transactional注释的类。

是否可以丢弃此类的特定单个方法的事务而无需@Transactional从类级别的声明中删除?如果是这样,请举一个例子

spring transactions spring-transactions

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

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

这并不完全像标题所说的那样,但接近。考虑这些 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
查看次数

为什么@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
查看次数