Transaction in multiple model repositories
- pseudonym
- Member | 57
Hi,
I wonder if there is a way to operate with transactions in multiple model
repositories. I have my repositories inherited from Repository class like in
this tutorial https://doc.nette.org/cs/quickstart.
I have for example three tables user
, announcement
and linking table userAnnouncement
which contains id
,
userID
and announcementID
and flag read
.
I want to begin transaction, insert announcement to announcement
table and fill linking table userAnnouncement
with pairs
userID
and announcementID
of inserted announcement. If
all rows are inserted successfully I want to commit transaction, otherwise
I want to rollback changes.
I am thinking that I create wrapper methods for
beginTransaction()
, commitTransaction()
and
rollback()
in class Repository
which all other
repositories extends.
My question is whether it will be working on all instances of repositories if I for example will call transaction methods on instance of UserRepository. Example:
// autowired AnnouncementRepository
private $announcementRepository;
// autowired userAnnouncementRepository
private $userAnnouncementRepository;
public function addAnnouncement($data, $users)
{
$this->announcementRepository->beginTransaction();
$row = $this->announcementRepository->add($data);
if ($row === false)
{
$result = false;
}
else
{
foreach ($users as $user)
{
$result = $this->userAnnouncementRepository->add($row->id, $user->id);
if ($result === false)
{
break;
}
}
}
if ($result === false)
{
$announcementRepository->rollbackTransaction();
}
else
{
$announcementRepository->commitTransaction();
}
}
Example is trimmed on purpose. It will be this snipped working? It will
rollback only table announcement
or also
userAnnouncement
?
I tried to begin transaction on both repositories but Nette said ‘There is
already an active transaction’ on the line of second
beginTransaction()
.
Edit:
I am sorry for unnecessary topic, I tried it and it working. But maybe someone
could explain it to me. It is because transaction are trigerred over database
and it has nothing to do with repositories? Could someone please provide exact
explanation?
Last edited by pseudonym (2013-10-14 17:08)
- Majkl578
- Moderator | 1364
It's sad Nette Database doesn't support emulate nested transactions. E.g. Doctrine does.
It is because transaction are trigerred over database and it has nothing to do with repositories?
Yes, transactions are directly sent to database. I guess you use MySQL, which does not support transactions nesting, so it ends up with an error.
- duke
- Member | 650
In MySQL there is a support for savepoints. To see how it's possible to emulate nested transactions using savepoints, you can take a look here.