第二个 Ucanaccess 事务并不总是被推送到 MDB

Posted

技术标签:

【中文标题】第二个 Ucanaccess 事务并不总是被推送到 MDB【英文标题】:2nd Ucanaccess transaction not always being pushed to MDB 【发布时间】:2015-12-13 11:20:36 【问题描述】:

我正在使用带有 JPA (EclipseLink) 的 Ucanaccess-3.0.2。对于大多数用例,它工作得很好。但我有一种情况,我

    开始交易 更新一行 提交事务 开始新事务 再次更新同一行 提交第二个事务。

此时第二个事务的数据在查询时可见(在新事务中),但如果我关闭 EntityManagerFactory 并打开 MDB,则第二个事务没有被持久化。

实体被描述为

/**
 * Primary Key of an Entry.
 */
@Embeddable
public class EntryPK implements Serializable 

    @Column(name = "Event", updatable = false)
    Integer eventId;

    @Column(name = "Athlete_no", updatable = false, insertable = false)
    Integer athleteId;


/**
 * My entity.
 */
@Entity
@Table(name = "Entry")
public class Entry 

    @EmbeddedId
    private EntryPK privateKey;

    @Column(name = "Event", updatable = true)
    private Integer eventId;

    @Column(name = "Athlete_no", updatable = true)
    private Integer athleteId;

    @Column(name = "Time")
    private Double time; // In seconds

    @Column(name = "DQCODE")
    private String dqCode;

注意,如果记录为空或正在清除记录,则事务将持续存在。但是,如果记录中已经有一些数据,那么它并不总是持续存在。其 100% 可重复,不是间歇性的。但是记录中数据的先前状态会影响下一次提交是否会持续到 MDB。

例如,从EntryeventId=1, athleteId=1 开始并更新到EntryeventId=1, athleteId=1, time=12.34 即可。如果我随后更新到 EntryeventId=1, athleteId=1, time=23.45,它将根据 JPA EntityManager 上的查询持续存在,但 不会 持续到 MDB。但如果我改为更新到 EntryeventId=1, athleteId=1, time=23.45, dqCode='XX',它保留到 MDB。

这可能是因为对中间 HSQL DB 进行了更改,但尚未写入 MDB?

如果是这样,我如何确保事务被推送到 MDB?

【问题讨论】:

【参考方案1】:

好的,解决方案很简单(感谢@GordThompson 的帮助)。

在提交事务时,我没有关闭 EntityManager。所以在某些情况下,交易会被收回。

自我注意:始终关闭 EntityManager。

【讨论】:

【参考方案2】:

请注意,您可能必须关闭并重新打开 MS Access 才能看到持久化的数据。 UCanAccess使用Jackcess更新Access数据库,Jackcess直接修改数据库文件,不使用Access Database Engine。因此,MS Access 在关闭并重新打开之前可能无法“看到”更改。

如果在 UCanAccess 上调用了提交,它总是会刷新并保留 Access 数据库中的数据。刷新绝对不可能被推迟,至少就 UCanAccess 层而言。也许对更高级别代码的审查可能会揭示您所遇到行为的可能解释。

【讨论】:

在提交时,MDB 永远不会在其他地方打开。我们之后打开它来检查结果。根据 EntityManager,提交显然已经发生,但没有到达 MDB。我怀疑 UCanAccess 正在放弃辅助更新,因为只有一个列发生了变化,并且没有为表定义主键。 同时,是否有另一条记录与检查更新的记录相同? @William re: “没有为表定义主键” - 请edit 你的问题解释你如何配置你的实体。我刚刚尝试重新创建您的问题,EclipseLink 在启动时失败,并显示“实体类 [class com.example.so34250537.Todo] 没有指定主键。”在这种情况下,minimal reproducible example 对于理解问题至关重要。 @GordThompson 我已经更新了问题,并包含了一个示例。 JPA 中为实体定义了一个主键。我的意思是 MS Access 表没有定义明确的主键索引。 @William - 我无法使用测试代码here 重新创建您的 UCanAccess 3.0.3 问题。第二个事务实际上确实被提交回 .mdb 数据库文件,即使我只更新 [time] 列。

以上是关于第二个 Ucanaccess 事务并不总是被推送到 MDB的主要内容,如果未能解决你的问题,请参考以下文章

为啥不需要的数据被推送到我的阵列中?

防止 viewcontroller 被推送到 splitviewcontroller 两次

UCanAccess 读取表的最后一列作为第一列[重复]

Cocoapods - podspec 验证但不能被推送到 repo

为啥在我的视图被推送到导航堆栈之前我的 UIAlertView 没有在屏幕上消失?

Bigint Division 总是返回零