我正在尝试使用SpringJTA-JPA-Hibernate了解事务传播的行为。
本质上,我正在尝试更新一个实体。为此,我编写了一个测试方法,其中我使用实体管理器(em)查找方法获取对象(所以现在这个对象是管理对象)。更新获取的对象的属性。然后可选地调用正在调用em.merge的服务层(服务层传播=必需)
现在我这里有三个变体:
> < li>
测试方法没有事务注释。更新提取的对象的属性,不调用服务层。
1.1. 结果级别 1 缓存不会更新,数据库也不会更新。
测试方法没有事务注释。更新提取对象的属性。调用服务层。
2.1.结果级别1缓存和数据库得到更新。
测试方法具有跨国注释,可以是以下任何一种。请参阅下表,了解测试方法的传播值和服务调用的结果。
(服务层传播=必需)
因此,要阅读上表,第1行表示如果Test方法具有事务传播=REQUIRED并且如果进行了服务层调用,则结果是更新到Level 1缓存,但不更新到DB
下面是我的测试用例
@Test
public void testUpdateCategory() {
//Get the object via entity manager
Category rootAChild1 = categoryService.find(TestCaseConstants.CategoryConstant.rootAChild1PK);
assertNotNull(rootAChild1);
rootAChild1.setName(TestCaseConstants.CategoryConstant.rootAChild1 + "_updated");
// OPTIONALLY call update
categoryService.update(rootAChild1);
//Get the object via entity manager. I believe this time object is fetched from L1 cache. As DB doesn't get updated but test case passes
Category rootAChild1Updated = categoryService.find(TestCaseConstants.CategoryConstant.rootAChild1PK);
assertNotNull(rootAChild1Updated);
assertEquals(TestCaseConstants.CategoryConstant.rootAChild1 + "_updated", rootAChild1Updated.getName());
List<Category> categories = rootAChild1Updated.getCategories();
assertNotNull(categories);
assertEquals(TestCaseConstants.CategoryConstant.rootAChild1_Child1,categories.get(0).getName());
}
服务层
@Service
public class CategoryServiceImpl implements CategoryService {
@Transactional
@Override
public void update(Category category) {
categoryDao.update(category);
}
}
刀
@Repository
public class CategoryDaoImpl {
@Override
public void update(Category category) {
em.merge(category);
}
}
问题:有人能解释为什么REQUIRED、REQUIRES_NEW和NESTED不会导致在DB中插入吗?
为什么在我的三个变体中,测试用例上缺少事务注释会导致数据库中的插入?
谢谢
您看到的<code>REQUIRED</code>、<code>NESTED</code>和<code>requireds_NEW</code>的效果是由于您检查更新太早
(我在这里假设您在测试方法到达断言的同时检查db更改,或者您在执行测试后以某种方式回滚测试方法事务)
很简单,您的断言仍然在测试方法中的@Transactional
注释创建的上下文中。因此,尚未调用数据库的隐式刷新。
在其他三种情况下,测试方法上的@Transactional
注释不会启动服务方法加入的事务。因此,事务仅跨越服务方法的执行,并且刷新在测试断言之前发生。
redis缓存一致性方案,网上统一比较认同的为 延迟双删 方案。即: 但所有文章都没有涉及到 数据库事务、 以及事务隔离性问题。 假如在一个数据库事务中,涉及到执行读写数据库操作 10 次, 那么问题是,删除缓存的时机是每次执行数据库操作之后即删除或更新缓存吗? 还是要先将事务内的数据库变动 缓存起来,等事务提交时,再一次性同步到底层redis? 在事务中更新缓存的话,带来的严重问题就是会破坏 数
我试图理解Spring事务概念。如下所示,我必须将数据插入两个不同的数据库(iSeries和DB2),但我们的iSeries版本不支持两阶段提交。要求是,只有当两个插入都成功时才应该提交事务,否则应该回滚。 如果我根据需要使用传播或REQUIRES\u NEW,我会得到错误“非法尝试使用现有的两阶段资源提交一阶段资源”。 但是如果我使用NOT_SUPPORTED或支持,它工作正常(即如果其中一个插
我有3列(时间,值,结果)的度量表。时间和值是时间序列数据库需要的基础。结果列标记可以具有以下值之一(成功/硬失败/软失败/未知)。 我想在给定的时间窗口内跟踪成功率(成功/总成功率)(因为我将在grafana上使用它,时间窗口可能会改变,并且应该支持动态时间范围查询) 我在流入量0.9上尝试过的东西: Grafana有一个百分比堆栈选项来显示计数值。不幸的是,它不显示百分比值。它只是显示了分布的
在下面的文章中说, 在此处输入链接描述 需要传播–支持当前交易;如果不存在,请创建一个新的。 下面是一个产品代码,然后是两个表的产品详细信息。 我的问题是什么时候会发生这种行为?我的意思是,当前交易怎么会结束?是在保存还是更新之后? 如果我们使用PROPAGATION_REQUIRED假设当前事务在插入产品后结束。然后一个新的事务来了,但是如果插入产品数量时出现任何故障,它只会回滚数量而不是输入的
我想使用spring测试框架测试hibernate Session的save()方法。@测试方法为: 我想刷新用户到数据库。我希望我的用户在此方法后在数据库中 然后我要使用spring data framework转到database并通过下一行获取这个保存的用户: 非常感谢您的回应。问题是方法flush()没有将我的用户放入数据库,我尝试了isolation.read_uncommitted,但
一、Attach数据库: ATTACH DATABASE语句添加另外一个数据库文件到当前的连接中,如果文件名为":memory:",我们可以将其视为内存数据库,内存数据库无法持久化到磁盘文件上。如果操作Attached数据库中的表,则需要在表名前加数据库名,如dbname.table_name。最后需要说明的是,如果一个事务包含多个Attached数据库操作,那么该事务仍然是原子的。见如下示例: