在我们的Symfony2项目中,我们希望确保跨资源的修改是事务性的。例如,像:
namespace ...;
use .../TransactionManager;
class MyService {
protected $tm;
public function __construct(TransactionManager $tm)
{
$this->tm = $tm;
}
/**
* @ManagedTransaction
*/
public function doSomethingAcrossResources()
{
...
// where tm is the transaction manager
// tm is exposing a Doctrine EntityManager adapter here
$this->tm->em->persist($entity);
...
// tm is exposing a redis adapter here
$this->tm->redis->set('foo', 'bar');
if ($somethingWentWrong) {
throw new Exception('Something went terribly wrong');
}
}
}
所以这里有几点需要注意:
这样的交易经理是否已经存在?有没有更好的方法来实现这些目标?我可能会忽略一些警告吗?
谢谢!
答案 0 :(得分:1)
事实证明,我们最终不需要确保资源的原子性。当涉及多个行/表时,我们确实希望与数据库交互成为原子,但我们决定使用事件驱动的体系结构。
如果更新redis在事件监听器内部失败,我们将停止传播,但它不是世界末日 - 允许我们通知用户成功操作(即使副作用不成功)
我们可以根据需要运行后台作业以偶尔更新redis。这使我们能够将核心业务逻辑集中在服务方法中,然后在成功时调度事件,从而允许发生非关键副作用(更新缓存,发送电子邮件,更新弹性搜索等),彼此隔离,在主要业务逻辑之外。