访问事务以提交或回滚的首选方式是什么?

发布于 2024-10-21 02:16:36 字数 709 浏览 5 评论 0原文

我了解事务如何工作以及一切按预期运行,但我不喜欢访问连接以提交或回滚事务的方式。

我有 3 个服务类可以访问同一个单例连接对象。我想将这三件事包装在一个事务中,所以我这样做:

try {
  $service1 = new ServiceOne;
  $service2 = new ServiceTwo;
  $service3 = new ServiceThree;

  $service1->insertRec1($data);
  $service2->deleteRec2($data);
  $service3->updateRec3($data);

  $service1->getSingletonConnection()->commit();
}
catch(Exception $ex) {
  $service1->getSingletonConnection()->rollback();
}

getSingletonConnection 返回的连接对象只是 oci8 连接的包装器,提交是 oci_commit ;回滚是oci_rollback

正如我所说,这是可行的,因为它们都访问相同的连接,但通过任意服务对象访问连接感觉是错误的。另外,我的应用程序中使用了两个不同的数据库,因此我需要确保检索并提交正确的数据库......但不确定是否有任何解决方法。

有没有更好的方法来处理交易?

I understand how transactions work and everything functions as expected, but I do not like the way I access connections to commit or rollback transactions.

I have 3 service classes that can access the same singleton connection object. I want to wrap these three things in a single transaction, so I do this:

try {
  $service1 = new ServiceOne;
  $service2 = new ServiceTwo;
  $service3 = new ServiceThree;

  $service1->insertRec1($data);
  $service2->deleteRec2($data);
  $service3->updateRec3($data);

  $service1->getSingletonConnection()->commit();
}
catch(Exception $ex) {
  $service1->getSingletonConnection()->rollback();
}

The connection object returned by getSingletonConnection is just a wrapper around the oci8 connection, and committing is oci_commit; rollback is oci_rollback.

As I said, this works because they are all accessing the same connection, but it feels wrong to access the connection through any arbitrary service object. Also, there are two different databases used in my app so I need to be sure that I retrieve and commit the correct one... not sure if there is any way around that though.

Is there a better way to handle transactions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

橘香 2024-10-28 02:16:37

感觉访问有问题
通过任意连接
服务对象。

我100%同意你的观点。

在我看来,如果每个服务仅构成数据库事务的一部分,那么该服务就不能直接负责确定要使用的数据库会话。您应该在定义事务的代码级别选择和管理连接。

因此,您当前的代码将被修改为:

try {
  $conn = getSingletonConnection();
  $service1 = new ServiceOne($conn);
  $service2 = new ServiceTwo($conn);
  $service3 = new ServiceThree($conn);

  $service1->insertRec1($data);
  $service2->deleteRec2($data);
  $service3->updateRec3($data);

  $conn->commit();
}
catch(Exception $ex) {
  $conn->rollback();
}

看起来这会简化处理您的两个数据库问题,因为只有一个地方可以决定使用哪个连接,并且您将直接引用该连接,直到您结束交易。

如果您想从单例连接扩展到连接池,这将是我能想到的保证所有三个服务调用使用相同连接的唯一方法。

it feels wrong to access the
connection through any arbitrary
service object.

I agree with you 100%.

It seems to me that if each service only makes up part of a database transaction, then the service cannot be directly responsible for determining the database session to use. You should select and manage the connection at the level of code that defines the transaction.

So your current code would be modified to something like:

try {
  $conn = getSingletonConnection();
  $service1 = new ServiceOne($conn);
  $service2 = new ServiceTwo($conn);
  $service3 = new ServiceThree($conn);

  $service1->insertRec1($data);
  $service2->deleteRec2($data);
  $service3->updateRec3($data);

  $conn->commit();
}
catch(Exception $ex) {
  $conn->rollback();
}

It seems like this would simplify dealing with your two-database issue, since there would only be one place to decide which connection to use, and you would hold a direct reference to that connection until you end the transaction.

If you wanted to expand from a singleton connection to a connection pool, this would be the only way I can think of to guarantee that all three service calls used the same connection.

又爬满兰若 2024-10-28 02:16:37

单个连接本质上没有任何问题。
如果您有多个连接,则每个连接都运行一个独立的事务。你基本上有两个选择。

  • 维持现有单
    每个的连接对象
    三个服务
  • 保持独立
    连接(以及相关开销)
    对于每个服务,以及提交/回滚
    每个单独的连接
    (不是特别安全,因为你
    无法保证ACID一致性
    然后)

作为绕过您要连接到的两个单独的数据库实例的方法:使用数据库链接,以便您只连接到单个数据库

There's nothing intrinsically wrong with a single connection.
If you have multiple connections, then each runs an independent transaction. You basically have two options.

  • Maintain the current single
    connection object for each of the
    three services
  • Maintain separate
    connections (with related overheads)
    for each service, and commit/rollback
    each individual connection separately
    (not particularly safe, because you
    can't guarantee the ACID consistency
    then)

As a way round the two separate database instances that you're connecting to: use db links so that you only connect to a single database

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文