CacheStoreAdapter存在錯誤。當其方法sessionEnd被調用時,CacheStoreSessionResource的連接總是被關閉。沒有任何例外。但事實上並沒有提交交易,數據庫也沒有任何變化。我的代碼非常簡單。所有這些都是根據Ignite的原始示例完成的。沒有提交Ignite CacheStoreAdapter
客戶
IgniteCache<String, String> typeCache = ignite.getOrCreateCache("typeCache");
try (Transaction tx = ignite.transactions().txStart(TransactionConcurrency.PESSIMISTIC,
TransactionIsolation.REPEATABLE_READ)) {
typeCache.put("code", "name");
tx.commit();
}
catch (Exception e) {
log.error("ERROR. Put Type: " + type, e);
}
服務器:
public class CacheJdbcTypeStore extends CacheStoreAdapter<String, String> {
@CacheStoreSessionResource
private CacheStoreSession ses;
@Override
public void write(Cache.Entry<? extends String, ? extends String> entry) {
String key = entry.getKey();
String val = entry.getValue();
try (Connection conn = connection(ses)) {
try (PreparedStatement st = conn.prepareStatement(
"insert into t_type (code, name) values (?, ?)")) {
st.setString(1, key);
st.setString(2, val);
st.executeUpdate();
}
}
catch (Exception e) {
throw new CacheWriterException("Failed to write Type " + val, e);
}
}
@Override
public void sessionEnd(boolean commit) {
try (Connection conn = ses.attachment()) {
if (conn != null && !conn.isClosed() && ses.isWithinTransaction()) {
if (commit)
conn.commit();
else
conn.rollback();
}
}
catch (SQLException e) {
throw new CacheWriterException("Failed to end store session of Type cache", e);
}
}
private Connection connection(CacheStoreSession ses) throws Exception {
if (ses.isWithinTransaction()) {
Connection conn = ses.attachment();
/************************************/
/* Here conn always is closed. WHY???? */
/* As result transaction is never commited !!!! */
/************************************/
if (conn == null || conn.isClosed()) {
conn = openConnection(false);
ses.attach(conn);
}
return conn;
}
else {
return openConnection(true);
}
}
// Opens JDBC connection.
private Connection openConnection(boolean autocommit) throws Exception {
Connection conn = DriverManager.getConnection(url);
conn.setAutoCommit(autocommit);
return conn;
}
@Override
public String load(final String key) {
return null;
}
@Override
public void delete(Object key) {
}
}
配置
<property name="cacheConfiguration">
<list>
<bean class="org.apache.ignite.configuration.CacheConfiguration">
<property name="name" value="typeCache" />
<property name="cacheMode" value="PARTITIONED" />
<property name="atomicityMode" value="TRANSACTIONAL" />
<property name="backups" value="1" />
<property name="cacheStoreFactory">
<bean class="javax.cache.configuration.FactoryBuilder"
factory-method="factoryOf">
<constructor-arg
value="ru.raiffeisen.cache.store.jdbc.CacheJdbcTypeStore" />
</bean>
</property>
<property name="readThrough" value="true" />
<property name="writeThrough" value="true" />
</bean>
</list>
</property>
感謝您的想法。我會檢查這個選項。 Just Ignite文檔包含JDBC事務處理方式的此片段: //只要在IgniteCache上調用「put(...)」方法,就會調用此mehtod。 @覆蓋公共無效寫入(Cache.Entry <龍,人>進入){ 試(連接康恩=連接()){ \t \t ......... } 趕上(的SQLException E){ 拋出新CacheWriterException(」無法寫[key =「+ key +」,val =「+ val +']',e); } } –
更新的答案,據我所知,這是一個在doc中的問題,應該修復 –
是的,你是對的。這是Ignite文檔中的問題。如果要在常規「try」語句內打開連接,則該代碼會將數據放入數據庫中。 –