【问题标题】:Hibernate CURRENT_TIMESTAMP and multi-entity transactions in MySQLMySQL 中的休眠 CURRENT_TIMESTAMP 和多实体事务
【发布时间】:2016-09-04 02:10:44
【问题描述】:

我有两个使用 JPA 声明的不同实体(A 和 B),并在同一个事务中使用 Hibernate(mysql 5.6.30、Hibernate 3.6.8 和 Spring 4.2.1)进行持久化。两个实体都包含此列:

`created_at` DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6)

当我在同一事务中创建 A 和 B 时,created_at 对于 A 和 B 会有所不同。

我的测试使用的是 Spring,并且定义如下:

@Autowired
private TransactionTemplate inTx;

@Test
public void test() {
    inTx.execute(__ -> {
       aRepository.add(a);
       bRepository.add(b);
       return null;
    });
}

我很确定实体在同一个事务中,因为 aRepository 和 bRepository 中的 add 方法是这样定义的:

@Transactional(propagation = Propagation.MANDATORY)

我还尝试将测试更改为如下所示:

@Test
public void test() {
    inTx.execute(__ -> {
       aRepository.add(a);
       Thread.sleep(1000);
       bRepository.add(b);
       return null;
    });
}

这会产生如下结果:

java.lang.AssertionError: [A and B should have the same timestamp]
Expecting:
 <[2016-05-09T14:16:28.531,
   2016-05-09T14:16:28.532]>
to contain only:
 <[2016-05-09T14:16:28.531]>
but the following elements were unexpected:
 <[2016-05-09T14:16:28.532]>

即时间戳非常接近但不一样。我的直觉表明,A 和 B 的 created_at 将完全相同相同,因为它们是同一事务的一部分。所以我的问题是:

  1. 这是预期的行为还是我做错了什么?
  2. 如果这是预期行为,是否有办法保持事务结束时间而不是实体创建时间? (这样created_at 时间戳对于保存在同一事务中的所有实体都是相同的)

【问题讨论】:

  • 1.是的(但在不同的数据库上可能会有所不同),2. 我不知道,除非您使用触发器或类似的东西。
  • 谢谢!也许您可以将其添加为答案,以便我接受?

标签: mysql spring hibernate jpa transactions


【解决方案1】:

这确实是预期的行为。只要将项目插入数据库,就会设置值(如果没有事先设置)。因此,根据您的服务器的速度,可能会有所不同。

如果您想使用数据库来控制这一点,您最好的选择是触发器,它根据事务结束更新时间。

您也可以在 Java 中通过在插入之前设置当前日期来执行此操作。一次创建一个日期实例并将其设置在所有实体上。这样数据库默认值就不会启动。

【讨论】:

    猜你喜欢
    • 2014-02-25
    • 2010-11-14
    • 2021-12-04
    • 1970-01-01
    • 2016-03-19
    • 2013-07-01
    • 1970-01-01
    • 2013-06-01
    • 1970-01-01
    相关资源
    最近更新 更多