简体   繁体   English

使用Hibernate Search + Infinispan Directory的事务ACID属性

[英]Transaction ACID properties with Hibernate Search + Infinispan Directory

I have the following setup: 我有以下设置:

  • JPA (2.0) through Hibernate (4.1) JPA(2.0)通过Hibernate(4.1)
  • Infinispan as 2nd level cache (5.1) Infinispan作为二级缓存(5.1)
  • Hibernate Search connected to Hibernate (4.1) Hibernate Search连接到Hibernate(4.1)
  • Infinispan as Directory for Hibernate Search (Lucene) Infinispan作为Hibernate搜索目录(Lucene)
  • Connected a JDBC CacheStore for the Infinispan Directory 连接Infinispan目录的JDBC CacheStore
  • PostgreSQL (9.1) database to store both entities and Lucene directory. PostgreSQL(9.1)数据库存储实体和Lucene目录。
  • Bitronix (2.1.2) as Transaction Manager Bitronix(2.1.2)作为事务管理器
  • I'm not using Java EE, but Spring (3.1) 我不是在使用Java EE,而是使用Spring(3.1)

Infinispan as Second Level Cache is fine, no recovery is needed and you can read changes in your own transaction because of the nature of the Cache. Infinispan作为二级缓存很好,不需要恢复,并且由于Cache的性质,您可以读取自己事务中的更改。

After hours reading source codes, when I update an Entity, Hibernate Search does not update the Lucene Directory but at the end of the transaction (if it commits), so it I wanted to do a search of the text I've just updated, inside the same transaction, wouldn't I be able? 在阅读源代码几小时后,当我更新实体时,Hibernate Search不会更新Lucene目录,但是在事务结束时(如果它提交),所以我想搜索我刚刚更新的文本,在同一笔交易里面,我不能吗?

But moreover, Hibernate Search does the updates to the Directory in a different thread, after transaction completion. 但是,在事务完成后,Hibernate Search会在不同的线程中对Directory进行更新。 So if one of the Directory Updates fails, then Lucene will be inconsistent to my entities? 因此,如果其中一个目录更新失败,那么Lucene将与我的实体不一致? And if something happened before the updates were dispatched to the Directory and a recovery was needed, would those updates be lost? 如果在将更新发送到目录并且需要恢复之前发生了某些事情,这些更新是否会丢失?

Assuming this "first" transaction committed successfully, the updates were sent to the Infinispan Directory. 假设此“第一”事务成功提交,更新将发送到Infinispan目录。 A new transaction would be started here. 这里将开始一项新交易。 By whom? 通过谁? Lucene has the options to send the updates using JMS. Lucene可以选择使用JMS发送更新。 Let's say that option is activated, so the JMS message initializes the new transaction. 假设选项已激活,因此JMS消息初始化新事务。

Infinispan will modify its memory directory with the updates it receives, but the persistent CacheStore will again be updated at this transaction completion, after commit. Infinispan将使用它接收的更新修改其内存目录,但是在提交后,持久的CacheStore将在此事务完成时再次更新。 Therefore there is a chance that if something happens while updating the jdbc CacheStore, it will be left with no updates, but Infinispan Memory Directory will have them applied. 因此,如果在更新jdbc CacheStore时发生某些事情,它将有可能没有更新,但Infinispan Memory Directory将应用它们。

My question is, considering that all the modules I'm using support transactions, and that they even support joining to global transactions (XA), is there a way to achieve true transactionality? 我的问题是,考虑到我使用的所有模块都支持事务,并且他们甚至支持加入全局事务(XA), 是否有办法实现真正​​的事务性? Maybe I'm just not seeing it. 也许我只是没有看到它。

I'm working on a very similar setup. 我正在进行一个非常类似的设置。 With these versions true transactionality is not possible. 使用这些版本,真正的事务性是不可能的。 There are a few reasons, some of which you have noted: 有几个原因,其中一些你注意到:

  1. Hibernate Search does index updates in commit phase Hibernate Search会在提交阶段对索引进行索引
  2. Hibernate Search processes on background threads - even when 'synchronous' Hibernate Search在后台线程上进行处理 - 即使是'同步'
  3. Infinispan cache store updates are done in commit phase Infinispan缓存存储更新在提交阶段完成

Here the transaction phase is important as the eventual inserts into the database need to be done in the main body of the transaction and committed at the end. 这里的事务阶段很重要,因为最终插入到数据库中需要在事务的主体中完成并在最后提交。

My solution was to ignore transactionality for index updates, it wasn't strictly necessary in my case. 我的解决方案是忽略索引更新的事务性,在我的情况下并不是绝对必要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM