使用以下代码,MySQL中的PHP“嵌套”事务是否可能成为现实?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了使用以下代码,MySQL中的PHP“嵌套”事务是否可能成为现实?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4351字,纯文字阅读大概需要7分钟。
内容图文
![使用以下代码,MySQL中的PHP“嵌套”事务是否可能成为现实?](/upload/InfoBanner/zyjiaocheng/886/ee68fa2cec784e34b1036d33298986b7.jpg)
好的,我正在寻找使用PHP在MySQL中进行“嵌套”事务的解决方案,并且正如您在MySQL文档中所知的那样,不可能在事务内进行事务(Mysql transactions within transactions).我试图使用http://php.net/manual/en/pdo.begintransaction.php中建议的Database类,但不幸的是,这对我来说是错误的,因为它的计数器范围是对象级别而不是类级别,为了解决此问题,我创建了具有计数器(名为$nest)的此类(TransactionController)静态的,它带来了使事务“线性”(带有“线性”)所需的类级别:我说的是:它显然是嵌套的,但是如果您看起来它不是嵌套的,那么事务将运行良好,您认为呢? ?(最后看例子,车主)
class TransactionController extends \\PDO {
public static $warn_rollback_was_thrown = false;
public static $transaction_rollbacked = false;
public function __construct()
{
parent :: __construct( ... connection info ... );
}
public static $nest = 0;
public function reset()
{
TransactionController :: $transaction_rollbacked = false;
TransactionController :: $warn_rollback_was_thrown = false;
TransactionController :: $nest = 0;
}
function beginTransaction()
{
$result = null;
if (TransactionController :: $nest == 0) {
$this->reset();
$result = parent :: beginTransaction();
}
TransactionController :: $nest++;
return $result;
}
public function commit()
{
$result = null;
if (TransactionController :: $nest == 0 &&
!TransactionController :: $transaction_rollbacked &&
!TransactionController :: $warn_rollback_was_thrown) {
$result = parent :: commit();
}
TransactionController :: $nest--;
return $result;
}
public function rollback()
{
$result = null;
if (TransactionController :: $nest >= 0) {
if (TransactionController :: $nest == 0) {
$result = parent :: rollback();
TransactionController :: $transaction_rollbacked = true;
}
else {
TransactionController :: $warn_rollback_was_thrown = true;
}
}
TransactionController :: $nest--;
return $result;
}
public function transactionFailed()
{
return TransactionController :: $warn_rollback_was_thrown === true;
}
// to force rollback you can only do it from $nest = 0
public function forceRollback()
{
if (TransactionController :: $nest === 0) {
throw new \PDOException();
}
}
}
class CarData extends TransactionController {
public function insertCar()
{
try {
$this->beginTransaction();
... (operations) ...
$this->commit();
}
catch (\PDOException $e) {
$this->rollback();
}
}
}
class PersonData extends TransactionController {
public function insertPerson( $person=null )
{
try {
$this->beginTransaction();
... (operations) ...
$this->commit();
}
catch (\PDOException $e) {
$this->rollback();
}
}
}
class CarOwnerData extends TransactionController {
public function createOwner()
{
try {
$this->beginTransaction();
$car = new CarData();
$car->insertCar();
$person = new PersonData();
$person->insertPerson();
... (operations) ...
$this->commit();
}
catch (\PDOException $e) {
$this->rollback();
}
}
}
$sellCar = new CarOwnerData();
$sellCar->createOwner();
UPDATE1:静态属性$warn_rollback_was_thrown已添加到TransactionController,以警告事务在执行的某个时刻失败,但没有回滚.
UPDATE2:当事务在某个时刻失败时,您可以使用forceRollback()让代码仍然运行到最后或最终停止它,例如,请参见以下代码:
<?php // inside the class PersonData
public function insertMultiplePersons( $arrayPersons )
{
try {
$this->beginTransaction();
if (is_array( $arrayPersons )) {
foreach ($arrayPersons as $k => $person) {
$this->insertPerson( $person );
if ($this->transactionFailed()) {
$this->forceRollback();
}
}
}
$this->commit();
}
catch (\PDOException $e) {
$this->rollback();
}
} ?>
解决方法:
正如@YourCommonSense在评论中指出的那样,您实际上并没有实现嵌套事务.
我不确定我是否喜欢在代码中的任何地方调用commit()的想法,但实际上并没有提交任何东西.
您的整个解决方案似乎是在减轻设计决策,以将事务代码放入插入函数中,而不必理会它.
您可以将插入操作与事务逻辑分开,并将这些函数调用包装在执行事务的单独函数中:
public/private function insertPerson( $person=null )
{
... (operations) ...
}
public function createPerson()
{
$person = new Person();
... (setup person) ...
$this->beginTransaction();
try {
$this->insertPerson($person);
$this->commit();
}
catch (\PDOException $e) {
$this->rollback();
}
}
如果您绝对确定需要始终在交易中插入此人,则可以在调用该交易时检查您是否在交易中:
public/private function insertPerson($person=null)
{
if (!$this->hasActiveTransaction){ // Needs implementing
throw new Exception('Must be called within a transaction');
}
...(operations)...
}
在我们的项目中,所有保存逻辑都在模型中,所有事务逻辑都在控制器级别.
我假设您知道,对于单个语句,不需要事务,因为它们是原子操作,并且您的代码表示更复杂的情况.
内容总结
以上是互联网集市为您收集整理的使用以下代码,MySQL中的PHP“嵌套”事务是否可能成为现实?全部内容,希望文章能够帮你解决使用以下代码,MySQL中的PHP“嵌套”事务是否可能成为现实?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。